HDU 3395 Special Fish 最小费用流/KM
http://acm.hdu.edu.cn/showproblem.php?pid=3395
A fish will spawn after it has been attacked. Each fish can attack one other fish and can only be attacked once.用KM,
当时用最小费用最大流的时候老是WA
看了AC神的 blog http://hi.baidu.com/aekdycoin/blog/item/3bc9df1fa2327d1340341755.html !!! 以后构图注意了
代码(第一个最大费用最大流):
#include<iostream> #include<cstdio> #include<cstring> #include<string> #define nMAX 205 #define mMAX 100005 #define inf 1<<28 struct Edge { int u,v,cap,cost,nxt; }edge[mMAX]; int pre[nMAX],head[nMAX],qu[nMAX],dis[nMAX],val[nMAX]; bool vs[nMAX]; int s_edge,maxf,ans; void addedge(int u,int v,int ca,int co) { edge[++s_edge].v=v; edge[s_edge].cap=ca; edge[s_edge].cost=co; edge[s_edge].nxt=head[u]; head[u]=s_edge; edge[++s_edge].v=u; edge[s_edge].cap=0; edge[s_edge].cost=-co; edge[s_edge].nxt=head[v]; head[v]=s_edge; } bool spfa(int s,int t,int n)//始点 终点 总点数 { int start=0, tail=1; for(int i=0;i<=n;i++) { dis[i]=-inf;//////////////////长注释的地方就是最大费用流要改的地方 vs[i]=0; } qu[0]=s; vs[s]=1; dis[s]=0; while(start!=tail) { int u=qu[start]; for(int e=head[u];e;e=edge[e].nxt) { int v=edge[e].v; if(edge[e].cap&&dis[v]<dis[u]+edge[e].cost)/////////// { dis[v]=dis[u]+edge[e].cost; pre[v]=e; if(!vs[v])//放if里面 { qu[tail++]=v; vs[v]=1; if(tail==nMAX)tail=0; } } } vs[u]=0; start++; if(start==nMAX)start=0; } if(dis[t]==-inf)return 0;///////////////////// return 1; } void end(int s,int t) { int p,u; for(u=t;u!=s;u=edge[p^1].v) { p=pre[u]; edge[p].cap-=1; edge[p^1].cap+=1; ans+=edge[p].cost; } } int main() { int i,j,s,t,m,N,p; char ch[105]; while(~scanf("%d",&N)) { if(N==0)break; s_edge=1; memset(head,0,sizeof(head)); for(i=1;i<=N;i++) scanf("%d",&val[i]); for(i=1;i<=N;i++) { for(j=1;j<=N;j++) { scanf("%1d",&p); if(p) { addedge(i,j+N,1,val[i]^val[j]); } } } s=0,t=2*N+1; for(i=1;i<=N;i++) { addedge(0,i,1,0); addedge(i+N,t,1,0); addedge(i,t,1,0); } ans=0; while(spfa(s,t,t))end(s,t); printf("%d\n",ans); } return 0; }