水题
最小割问题
考察什么?
冲突。
这种题不是没有过啊
有一个就是激光打别人的就是利用这个思想(搞忘做题解了,结果没权限了WOC)
利用S-T表示若联通则依旧有冲突
把S表示赞成,T表示不赞成
赞成的连T流1
不赞成的连S流1
如果有一对基友,两两双向连边!注意是无向边。
不会出事?
如果存在要割只会割形态学S-T的边
所以没事
#include<bits/stdc++.h>
using namespace std;
inline void read(int &x){
x=0;
int 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();
}
x*=f;
}
const int N=1e6+10;
int INF=1e9+7;
struct Front_star{
int u,v,w,nxt;
}e[N*4];
int cnt=1;
int first[N]={};
void addedge(int u,int v,int w){
cnt++;
e[cnt].u=u;
e[cnt].v=v;
e[cnt].w=w;
e[cnt].nxt=first[u];
first[u]=cnt;
}
void add(int u,int v,int w){
addedge(u,v,w);
addedge(v,u,0);
}
//
int d[N]={};
int S=0;
int T;
queue<int> q;
bool BFS(){
for(int i=S;i<=T;i++)d[i]=-1;
d[S]=1;
q.push(S);
while(!q.empty()){
int x=q.front();
q.pop();
for(int i=first[x];i;i=e[i].nxt){
int v=e[i].v;
if(e[i].w&&d[v]==-1){
d[v]=d[x]+1;
q.push(v);
}
}
}
return d[T]!=-1;
}
int dfs(int st,int ed,int nowdat){
if(st==ed){
return nowdat;
}
int dat=0;
for(int i=first[st];i;i=e[i].nxt){
int v=e[i].v;
if(e[i].w&&d[v]==d[st]+1){
int now=min(nowdat-dat,e[i].w);
now=dfs(v,ed,now);
e[i].w-=now;
e[i^1].w+=now;
dat+=now;
if(nowdat==dat){
return dat;
}
}
}
if(!dat){
d[st]=-2;
}
return dat;
}
int Dinic(){
int ret=0;
while(BFS()){
ret+=dfs(S,T,INF);
}
return ret;
}
int n,m;
int main(){
read(n);
read(m);
T=n+10;
for(int i=1;i<=n;i++){
int x;
read(x);
if(x==0){
add(S,i,1);
}
else{
add(i,T,1);
}
}
for(int i=1;i<=m;i++){
int x,y;
read(x);
read(y);
add(x,y,1);
add(y,x,1);
}
cout<<Dinic();
}