一定注意inf要开的非常大。要不然。。。嘿嘿嘿。
因为流量可能有交叉,那么要b1,b2进行交换再来跑一次。
1A很爽。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define maxv 650 #define maxe 250500 #define inf 9999999999999999 using namespace std; struct edge { long long v,f,nxt; }e[maxe]; long long g[maxv],n,a1,a2,an,b1,b2,bn,nume=1,map[55][55],s,t,flag; long long dis[maxv]; queue <long long> q; bool vis[maxv]; char ss[55]; void addedge(long long u,long long v,long long f) { e[++nume].v=v; e[nume].f=f; e[nume].nxt=g[u]; g[u]=nume; e[++nume].v=u; e[nume].f=0; e[nume].nxt=g[v]; g[v]=nume; } void build(long long type) { memset(g,0,sizeof(g)); nume=1; for (long long i=1;i<=n;i++) for (long long j=1;j<=n;j++) if (map[i][j]==1) addedge(i,j,2); else if (map[i][j]==2) addedge(i,j,inf); addedge(s,a1,2*an);addedge(a2,t,2*an); if (type==1) {addedge(s,b1,2*bn);addedge(b2,t,2*bn);} else {addedge(s,b2,2*bn);addedge(b1,t,2*bn);} } bool bfs() { while (!q.empty()) q.pop(); fill(dis+1,dis+t+1,-1); memset(vis,false,sizeof(vis)); q.push(s);dis[s]=0;vis[s]=true; while (!q.empty()) { long long head=q.front(); q.pop(); for (long long i=g[head];i;i=e[i].nxt) { long long v=e[i].v; if ((e[i].f) && (vis[v]==false)) { dis[v]=dis[head]+1; vis[v]=true; q.push(v); } } } if (dis[t]==-1) return false; return true; } long long dinic(long long x,long long low) { if (x==t) return low; else { long long ret=0; for (long long i=g[x];i;i=e[i].nxt) { long long v=e[i].v; if ((e[i].f) && (dis[v]==dis[x]+1)) { long long dd=dinic(v,min(low,e[i].f)); e[i].f-=dd;e[i^1].f+=dd; ret+=dd;low-=dd; } } if (ret==0) dis[x]=-1; return ret; } } void work(long long type) { long long ret=0; build(type); while (bfs()) ret+=dinic(s,inf); if (ret==an*2+bn*2) flag=1; else flag=0; } int main() { while (scanf("%lld%lld%lld%lld%lld%lld%lld",&n,&a1,&a2,&an,&b1,&b2,&bn)!=EOF) { a1++;a2++;b1++;b2++; flag=0; memset(map,0,sizeof(map)); s=0;t=n+1; for (long long i=1;i<=n;i++) { scanf("%s",ss); for (long long j=0;j<n;j++) { if (ss[j]=='O') map[i][j+1]=1; else if (ss[j]=='N') map[i][j+1]=2; } } work(1); if (flag==1) work(2); if (flag==1) printf("Yes\n"); else printf("No\n"); } return 0; }