无向图
题目描述:
小W在研究图论!
现在,小W有一张n个点m条边的无向简单图。每个点都有点权,第i个点的权值为ai。小W现在需要删掉若干个点删掉某个点时,会将与这个点相连的边也全部删除。
现在,小W需要解决一个问题:如何选择性地删掉一部分点,使得在删掉的点的点权之和尽量小的情况下,剩下的边的数量为偶数?
输入格式:
输入的第一行为两个正整数n,m。接下来一行n个正整数a1,···,an,描述了每个点的权值。接下来m行,每行两个正整数u, v,描述了图中的一条边。
输出格式:
输出共一行,表示使剩下的边数量为偶数的所有删除点的方法中,删掉的点的点权之和的最小值。
样例:
样例输入
5 5
1 2 3 4 5
1 2
1 3
1 4
1 5
2 3
样例输出
3
如果边的条数是偶输出0
如果是奇的话有两种情况
1.删一条点权最小的入度为奇数的点
2.删两个被一条边相连的入度为偶数的店
取最小值输出即可,思路简单。
程序:
#include<bits/stdc++.h> using namespace std; const int N=1e5+10; int n,m,d[N],a[N]; vector<int > mp[N]; int main() { ios::sync_with_stdio(false); cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]; memset(d,0,sizeof d); for(int i=1;i<=m;i++) { int u,v; cin>>u>>v; mp[u].push_back(v); mp[v].push_back(u); d[u]++; d[v]++; } if(m%2==0) { cout<<"0"; return 0; } int t1=0x3f3f3f3f; for(int i=1;i<=n;i++) if(d[i]%2==1) t1=min(t1,a[i]); int t2=0x3f3f3f3f; for(int i=1;i<=n;i++) { if(d[i]%2==1) continue; for(int j=0;j<mp[i].size();j++) { if(d[mp[i][j]]%2==0) { t2=min(t2,a[i]+a[mp[i][j]]); } } } cout<<min(t2,t1); return 0; }
标签:int,点权,删掉,样例,无向,mp From: https://www.cnblogs.com/wjk53233/p/17132253.html