[kuangbin带你飞]专题十一 网络流 A POJ - 3436
2017-04-19 21:36
423 查看
题目地址:https://vjudge.net/contest/68128#problem/A
思路:添加一个超级汇点一个超级源点,将所有进入状态不含1的点与超级源点相连,将所有输出状态不含0的点与超级汇点相连,将所有输入状态和输出状态可以匹配的点相连。这样建图就可以把问题转化为最大流问题。路径输出判断该条边的流量是否有使用即可。
AC代码:
思路:添加一个超级汇点一个超级源点,将所有进入状态不含1的点与超级源点相连,将所有输出状态不含0的点与超级汇点相连,将所有输入状态和输出状态可以匹配的点相连。这样建图就可以把问题转化为最大流问题。路径输出判断该条边的流量是否有使用即可。
AC代码:
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int MAXN = 100+10; const int MAXM = 1e6+10; const int INF = 0x3f3f3f3f; struct edge{ int u,v,next,cap,flow; }edge[MAXM]; int tol; int head[MAXN]; struct pos{ int a[15]; int b[15]; int c; }m[MAXN]; void init(){ tol=0; memset(head,-1,sizeof(head)); } void addedge(int u,int v,int w){ edge[tol].u=u; edge[tol].v=v; edge[tol].cap=w; edge[tol].next=head[u]; //printf("head:%d\n",head[u]); head[u]=tol++; edge[tol].u=v; edge[tol].v=u; edge[tol].cap=0; edge[tol].next=head[v]; head[v]=tol++; } int dep[MAXN],cur[MAXN],sta[MAXN]; bool bfs(int s,int t){ queue<int>q; memset(dep,-1,sizeof(dep)); dep[s]=0; q.push(s); while(!q.empty()){ int u=q.front(); //printf("%d\n",u); q.pop(); for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; //printf("%d\n",i); //getchar(); if(edge[i].cap>0 && dep[v]==-1){ dep[v]=dep[u]+1; if(v==t) return true; q.push(v); } } } return false; } int dfs(int a,int b,int s,int t){ int r=0; if(a==t) return b; for(int i=head[a];i!=-1 && r<b;i=edge[i].next){ int u=edge[i].v; if(edge[i].cap>0 && dep[u]==dep[a]+1){ int x=min(edge[i].cap,b-r); x=dfs(u,x,s,t); r+=x; edge[i].cap-=x; edge[i^1].cap+=x; } } if(!r) dep[a]=-2; return r; } int dinic(int s,int t){ int total=0,temp; while(bfs(s,t)){ // printf("hahaha"); while(temp=dfs(s,INF,s,t)) total+=temp; // printf("%d\n",total); } return total; } int p,n; int main(){ init(); scanf("%d%d",&p,&n); for(int i=1;i<=n;i++){ scanf("%d",&m[i].c); for(int j=0;j<p;j++) scanf("%d",&m[i].a[j]); for(int j=0;j<p;j++) scanf("%d",&m[i].b[j]); } //超级源点 for(int i=1;i<=n;i++){ bool temp=true; for(int j=0;j<p;j++){ if(m[i].a[j]==1){ temp=false; break; } } if(temp) addedge(0,i,m[i].c); } //超级汇点 for(int i=1;i<=n;i++){ bool temp=true; for(int j=0;j<p;j++){ if(m[i].b[j]==0){ temp=false; break; } } if(temp) addedge(i,n+1,m[i].c); } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(i==j) continue; bool temp=true; for(int k=0;k<p;k++){ if(m[i].b[k]+m[j].a[k]==1){ temp=false; break; } } if(temp) addedge(i,j,m[i].c); } } int ans=dinic(0,n+1); printf("%d ",ans); int w=0; for(int i=0;i<tol;i+=2){ if(edge[i].u==0 || edge[i].v==n+1) continue; if(edge[i].cap!=m[edge[i].u].c) w++; } printf("%d\n",w); for(int i=0;i<tol;i+=2){ if(edge[i].u==0 || edge[i].v==n+1) continue; if(edge[i].cap!=m[edge[i].u].c) printf("%d %d %d\n",edge[i].u,edge[i].v,m[edge[i].u].c-edge[i].cap); } }
相关文章推荐
- [kuangbin带你飞]专题十一 网络流 B POJ - 3281
- [kuangbin带你飞]专题十一 网络流 D POJ – 2195
- [kuangbin带你飞]专题十一 网络流
- [kuangbin带你飞]专题十一 网络流
- [kuangbin带你飞]专题1 简单搜索 E - Find The Multiple POJ - 1426
- POJ 3984 迷宫问题(kuangbin带你飞 专题一:简单搜索)
- [kuangbin带你飞]专题五 并查集 A POJ 2236
- [kuangbin带你飞]专题六 最小生成树 G POJ 2349
- POJ - 2251 bfs [kuangbin带你飞]专题一
- [kuangbin带你飞]专题一 简单搜索-C - Catch That Cow POJ - 3278
- POJ 3087 Shuffle'm Up(kuangbin带你飞 专题一:简单搜索)专题一完结
- [kuangbin带你飞]专题七 线段树 C POJ 3468
- [kuangbin带你飞]专题一 简单搜索 K - 迷宫问题 POJ 3984
- [kuangbin带你飞]专题五 并查集 B POJ 1611
- [kuangbin带你飞]专题五 并查集 G POJ 1456
- [kuangbin带你飞]专题六 最小生成树 A POJ 1251
- [kuangbin带你飞]专题六 最小生成树 B POJ 1287
- [kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher G POJ 2406
- POJ - 3984 迷宫问题 [kuangbin带你飞]专题一 简单搜索
- POJ 3126 Prime Path(kuangbin带你飞 专题一:简单搜索)