1934: [Shoi2007]Vote 善意的投票
Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 2353 Solved: 1470
[Submit][Status][Discuss]
Description
幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉。对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神。虽然每个人都有自己的主见,但是为了照顾一下自己朋友的想法,他们也可以投和自己本来意愿相反的票。我们定义一次投票的冲突数为好朋友之间发生冲突的总数加上和所有和自己本来意愿发生冲突的人数。 我们的问题就是,每位小朋友应该怎样投票,才能使冲突数最小?
Input
第一行只有两个整数n,m,保证有2≤n≤300,1≤m≤n(n-1)/2。其中n代表总人数,m代表好朋友的对数。文件第二行有n个整数,第i个整数代表第i个小朋友的意愿,当它为1时表示同意睡觉,当它为0时表示反对睡觉。接下来文件还有m行,每行有两个整数i,j。表示i,j是一对好朋友,我们保证任何两对i,j不会重复。
Output
只需要输出一个整数,即可能的最小冲突数。
Sample Input
3 3
1 0 0
1 2
1 3
3 2
1 0 0
1 2
1 3
3 2
Sample Output
1
HINT
在第一个例子中,所有小朋友都投赞成票就能得到最优解
Source
设一个s一个t
每一个小盆友i支持午觉的由s向他连一条权值为1的边,不支持的由i向t连一条边
小盆友直接互相连一条权值为1的边,从s到t跑一遍最小割即可
由于要建双向边,所以边的范围是n*(n-1)!!!!!!!!!!!
1 #include "bits/stdc++.h" 2 using namespace std; 3 typedef long long LL; 4 const int MAX=305; 5 const int M=MAX*MAX; 6 int n,m,s,t; 7 int tot,head[MAX],adj[M],wei[M],next[M]; 8 int deep[MAX],cur[MAX]; 9 inline int read(){ 10 int an=0,x=1;char c=getchar(); 11 while (c<'0' || c>'9') {if (c=='-') x=-1;c=getchar();} 12 while (c>='0' && c<='9') {an=(an<<3)+(an<<1)+c-'0';c=getchar();} 13 return an*x; 14 } 15 void addedge(int u,int v,int w){ 16 tot++;adj[tot]=v,wei[tot]=w,next[tot]=head[u],head[u]=tot; 17 } 18 bool bfs(){ 19 int i,j,u; 20 memset(deep,127,sizeof(deep)); 21 deep[s]=0; 22 queue <int> q;q.push(s); 23 while (!q.empty()){ 24 u=q.front();q.pop(); 25 for (i=head[u];i;i=next[i]){ 26 if (deep[adj[i]]>1e9 && wei[i]>0) 27 deep[adj[i]]=deep[u]+1,q.push(adj[i]); 28 } 29 } 30 return deep[t]<1e9; 31 } 32 int dfs(int x,int flo){ 33 if (x==t || flo==0) return flo; 34 int j; 35 for (int &i=cur[x];i;i=next[i]){ 36 if (deep[adj[i]]==deep[x]+1 && wei[i]>0){ 37 j=dfs(adj[i],min(flo,wei[i])); 38 if (j){ 39 wei[i]-=j,wei[i^1]+=j; 40 return j; 41 } 42 } 43 } 44 return 0; 45 } 46 int main(){ 47 freopen ("vote.in","r",stdin);freopen ("vote.out","w",stdout); 48 int i,j,u,v; 49 n=read(),m=read();tot=1;s=n+1,t=n+2; 50 for (i=1;i<=n;i++){ 51 u=read(); 52 if (u==1) addedge(s,i,1),addedge(i,s,0); 53 else addedge(i 54 ,t,1),addedge(t,i,0); 55 } 56 for (i=1;i<=m;i++){ 57 u=read();v=read(); 58 addedge(u,v,1),addedge(v,u,1); 59 } 60 int flow=0,dd; 61 while (bfs()){ 62 for (i=1;i<=n+2;i++) cur[i]=head[i]; 63 while (dd=dfs(s,1e9)) flow+=dd; 64 } 65 printf("%d",flow); 66 return 0; 67 }
未来是什么样,未来会发生什么,谁也不知道。
但是我知道,
起码从今天开始努力,
肯定比从明天开始努力,
要快一天实现梦想。
千里之行,始于足下! ——《那年那兔那些事儿》