bzoj 1585: [Usaco2009 Mar]Earthquake Damage 2 地震伤害
Description
Farmer John的农场里有P个牧场,有C条无向道路连接着他们,第i条道路连接着两个牧场Ai和Bi,注意可能有很多条道路连接着相同的Ai和Bi,并且Ai有可能和Bi相等。Farmer John在1号牧场里。由于地震,某些牧场被损坏,但由于信春哥,C条道路没有一条损坏。有N头奶牛,他们在不同的牧场里,于是N <= P。他们一一向Farmer John报告。第i头奶牛报告给Farmer John一个整数Report_i,代表第Report_i个牧场没有损毁,但不能够从第Report_i个牧场经过一些没有损坏的牧场到达1号牧场。现在Farmer John想知道,最少有多少损坏的牧场。
Input
第一行三个整数 P,C,N
第2..C+1行:每行两个整数Ai,Bi
第C+2..C+N+1行:第C+1+i行包含一个整数,Report_i
Output
一个整数,代表最少有多少损坏的牧场
Sample Input
5 5 2
1 2
2 3
3 5
2 4
4 5
4
5
1 2
2 3
3 5
2 4
4 5
4
5
Sample Output
1
【数据规模】
1 <= P <=3000
1 <= C <=20000
【数据规模】
1 <= P <=3000
1 <= C <=20000
HINT
本题是最小割,根据最大流来求。
裂点法,第i个点列成2*i-1和2*i
如果第i个点一定不能被损坏,那么2i-1到2*i的容量就是无穷大,否则容量就是1.
1 #include<bits/stdc++.h> 2 using namespace std; 3 int const N=3000+10; 4 int const M=20000+10; 5 int const inf=1e6; 6 struct edge{ 7 int to,nt,cp,fl; 8 }e[M<<3]; 9 int s,t,n,m,k,h[N<<1],cnt,x[M],y[M],vis[N],dist[N<<1],q[N<<1],w[N<<1]; 10 void add(int a,int b,int c){ 11 e[cnt].to=b; e[cnt].cp=c; e[cnt].fl=0; e[cnt].nt=h[a]; h[a]=cnt++; 12 e[cnt].to=a; e[cnt].cp=0; e[cnt].fl=0; e[cnt].nt=h[b]; h[b]=cnt++; 13 } 14 int dinic_bfs(){ 15 memset(dist,-1,sizeof(dist)); 16 int cl=0; q[cl++]=s; dist[s]=0; 17 for(int i=0;i<cl;i++){ 18 int x=q[i]; 19 for(int j=h[x];j!=-1;j=e[j].nt){ 20 int v=e[j].to; 21 if(e[j].cp>e[j].fl && dist[v]==-1){ 22 dist[v]=dist[x]+1; 23 q[cl++]=v; 24 } 25 } 26 } 27 return dist[t]>=0; 28 } 29 int dinic_dfs(int x,int flow){ 30 if(x==t) return flow; 31 for(int &i=w[x];i!=-1;i=e[i].nt){ 32 int v=e[i].to,tmp=0; 33 if(e[i].cp>e[i].fl && dist[v]==dist[x]+1 && (tmp=dinic_dfs(v,min(flow,e[i].cp-e[i].fl)))){ 34 e[i].fl+=tmp; 35 e[i^1].fl-=tmp; 36 return tmp; 37 } 38 } 39 return 0; 40 } 41 int main(){ 42 scanf("%d%d%d",&n,&m,&k); 43 for(int i=1;i<=m;i++) 44 scanf("%d%d",&x[i],&y[i]); 45 while (k--){ 46 int v; 47 scanf("%d",&v); 48 vis[v]=1; 49 } 50 memset(h,-1,sizeof(h)); 51 for(int i=1;i<=n;i++) 52 if(!vis[i] && i!=1){ 53 add(2*i-1,2*i,1); 54 } else add(2*i-1,2*i,inf); 55 s=1; 56 t=2*n+1; 57 for(int i=1;i<=n;i++) 58 if(vis[i]) add(2*i-1,t,inf); 59 for(int i=1;i<=m;i++){ 60 add(2*x[i],2*y[i]-1,inf); 61 add(2*y[i],2*x[i]-1,inf); 62 } 63 int tmp,ans=0; 64 while (dinic_bfs()){ 65 memcpy(w,h,sizeof(h)); 66 while ((tmp=dinic_dfs(s,inf))) 67 ans+=tmp; 68 } 69 cout<<ans<<endl; 70 return 0; 71 }