BZOJ 1934 [Shoi2007]Vote 善意的投票 最小割
1934: [Shoi2007]Vote 善意的投票
Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 1444 Solved: 878
[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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//1085422276 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<queue> #include<cmath> #include<map> #include<bitset> #include<set> #include<vector> using namespace std ; typedef long long ll; #define mem(a) memset(a,0,sizeof(a)) #define meminf(a) memset(a,127,sizeof(a)); #define memfy(a) memset(a,-1,sizeof(a)) #define TS printf("111111\n"); #define FOR(i,a,b) for( int i=a;i<=b;i++) #define FORJ(i,a,b) for(int i=a;i>=b;i--) #define READ(a,b,c) scanf("%d%d%d",&a,&b,&c) #define inf 10000000 #define maxn 300+10 inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9') {if(ch=='-')f=-1; ch=getchar();} while(ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x*f; } //**************************************** struct ss { int to,u,next,v; }e[maxn*20000]; int n,m; int S=0,T=301; int head[maxn],t,ans,d[maxn]; void add(int u,int v,int w) { e[t].to=v; e[t].next=head[u]; e[t].v=w; head[u]=t++; } void init() { mem(head);t=1; } int dfs(int x,int f) { if(x==T)return f; int w,used=0; for(int i=head[x];i&&f;i=e[i].next) { if(e[i].v>0&&d[e[i].to]==d[x]+1) { w=dfs(e[i].to,min(f-used,e[i].v)); used+=w; e[i].v-=w; e[i^1].v+=w; if(used==f)return f; } } if(!used)d[x]=-1; return used; } bool bfs() { queue<int >q; memfy(d); d[S]=0; q.push(S); while(!q.empty()) { int k=q.front(); q.pop(); for(int i=head[k];i;i=e[i].next) { if(d[e[i].to]==-1&&e[i].v>0) { d[e[i].to]=d[k]+1; q.push(e[i].to); } } } return d[T]!=-1; } void dinic() { ans=0; while(bfs())ans+=dfs(S,inf); } int main() { int a,b; init(); scanf("%d%d",&n,&m); FOR(i,1,n) { scanf("%d",&a); if(a==1) { add(S,i,1); add(i,S,1); } else add(i,T,1),add(T,i,1); } FOR(i,1,m) { scanf("%d%d",&a,&b); add(a,b,1);add(b,a,1); } dinic(); cout<<ans<<endl; return 0; }