bzoj1433(网络流)

来源:互联网 发布:治痘痘最好的方法知乎 编辑:程序博客网 时间:2024/05/23 19:19


这里的一条流所代表的意义就是非常显然的了,就是给一个人睡安排一个床

构造二分图,最大流判定

源点向所有需要床位的连边,有床位的向汇点连边,如果i可以睡j的床i向j‘连边,然后跑最大流判定


#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#include<cmath>#include<queue>using namespace std;const int inf=0x3f3f3f3f;int n,s,t;bool stu[55],ghm[55];int id1[55],id2[55];int head[300],cur[300],tot,lev[300];struct aa{int pre,cap,flow,to;}edge[100050];void addedge(int x,int y,int z){edge[++tot].to=y;edge[tot].cap=z;edge[tot].pre=head[x];head[x]=tot;edge[++tot].to=x;edge[tot].cap=0;edge[tot].pre=head[y];head[y]=tot;}void init(){memset(stu,false,sizeof(stu));memset(ghm,false,sizeof(ghm));memset(head,0,sizeof(head));tot=0;memset(edge,0,sizeof(edge));memset(id1,0,sizeof(id1));memset(id2,0,sizeof(id2));}bool bfs(){memset(lev,0,sizeof(lev));lev[s]=1;queue<int> q;q.push(s);while (!q.empty()){int u=q.front();q.pop();for (int i=head[u];i;i=edge[i].pre)if (edge[i].cap>edge[i].flow&&lev[edge[i].to]==0){lev[edge[i].to]=lev[u]+1;if(edge[i].to==t) return true;q.push(edge[i].to);}}return false;}int dfs(int u,int maxflow){if (u==t||maxflow==0) return maxflow;int ans=0;for (int &i=cur[u];i;i=edge[i].pre)if (lev[edge[i].to]==lev[u]+1){int flow=dfs(edge[i].to,min(maxflow,edge[i].cap-edge[i].flow));ans+=flow;maxflow-=flow;edge[i].flow+=flow;edge[((i-1)^1)+1].flow-=flow;if (maxflow==0) return ans;}return ans;}int work(){int ans=0;while (bfs()){for (int i=s;i<=t;i++) cur[i]=head[i];ans+=dfs(s,inf);}return ans;}int main(){int T;scanf("%d",&T);for (int k=1;k<=T;k++){init();scanf("%d",&n);int x,bj=0,total=0;for (int i=1;i<=n;i++) id1[i]=++bj,id2[i]=++bj;t=bj+1,s=0;for (int i=1;i<=n;i++) scanf("%d",&stu[i]);for (int i=1;i<=n;i++){scanf("%d",&x);if (!stu[i]){addedge(s,id1[i],1);total++;continue;}ghm[i]=x;if (x==0) addedge(s,id1[i],1),addedge(id2[i],t,1),addedge(id1[i],id2[i],1),total++;else addedge(id2[i],t,1);}for (int i=1;i<=n;i++)for (int j=1;j<=n;j++){scanf("%d",&x);if(x&&!ghm[i]) addedge(id1[i],id2[j],1);}if (work()==total) printf("%c%c%c\n",94,95,94);else printf("%c%c%c\n",84,95,84);}return 0;}

总结

1:对于最大流问题来说,一般就是一条流代表一种方案,实际上并没有见到其他的意义

0 0
原创粉丝点击