题目描述
幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉。对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神。虽然每个人都有自己的主见,但是为了照顾一下自己朋友的想法,他们也可以投和自己本来意愿相反的票。我们定义一次投票的冲突数为好朋友之间发生冲突的总数加上和所有和自己本来意愿发生冲突的人数。
我们的问题就是,每位小朋友应该怎样投票,才能使冲突数最小?
输入输出格式
输入格式:
文件的第一行只有两个整数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不会重复。
输出格式:
只需要输出一个整数,即可能的最小冲突数。
输入输出样例
输入样例#1:
3 3
1 0 0
1 2
1 3
3 2
输出样例#1:
1
说明
2≤n≤300,1≤m≤n(n-1)/2。
题解:因为并没有要求统计最终情况,所以是水题啦。。。
要睡觉的i就add(s,i,1)否则add(i,t,1)
对于每一对意愿不同的小朋友a,b(a要睡觉b不要睡觉)add(a,b,1)
然后套板子。
// It is made by XZZ
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
#define rep(a,b,c) for(int a=b;a<=c;a++)
#define drep(a,b,c) for(int a=b;a>=c;a--)
#define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
#define il inline
#define rg register
#define vd void
#define t (dis[i])
typedef long long ll;
il int gi(){
rg int x=;rg char ch=getchar();
while(ch<''||ch>'')ch=getchar();
while(ch>=''&&ch<='')x=x*+ch-'',ch=getchar();
return x;
}
const int maxn=,maxm=*,S=,T=;
int fir[maxn],nxt[maxm],dis[maxm],w[maxm],id=;
il vd add(int a,int b,int c){
nxt[++id]=fir[a],fir[a]=id,dis[id]=b,w[id]=c;
if(c)add(b,a,);
}
int dep[maxn];
inline bool BFS() {
int que[maxn],hd=,tl=;
memset(dep,,sizeof dep);
que[hd]=S;
bool yes[maxn]= {};
yes[S]=,dep[S]=;
while(tl-hd) {
int now=que[hd];
for(int i=fir[now]; i; i=nxt[i])
if(w[i]>&&!yes[t])
yes[t]=,que[tl++]=t,dep[t]=dep[now]+;
++hd;
}
return yes[T];
}
inline int Dinic(int now,int h) {
if(now==T)return h;
int ans=;
for(int i=fir[now]; i; i=nxt[i])
if(w[i]>&&dep[t]==dep[now]+) {
int D=Dinic(t,min(h,w[i]));
w[i]-=D,w[i^]+=D,ans+=D,h-=D;
if(h==)return ans;
}
return ans;
}
bool k[maxn];
int main(){
int n=gi(),m=gi();
rep(i,,n){
k[i]=gi();
if(k[i])add(S,i,);
else add(i,T,);
}
rep(i,,m){
int a=gi(),b=gi();
if(k[a]^k[b]){
if(k[a])add(a,b,);
else add(b,a,);
}
}
int flow=;
while(BFS())flow+=Dinic(S,);
printf("%d\n",flow);
return ;
}