HDU 4975 最大流+判断环
来源:互联网 发布:linux gid是什么意思 编辑:程序博客网 时间:2024/05/21 08:13
点击打开链接
题意:给定的分别是每行值的和,每列值的和,每个元素的值在0~9之间,问有多少种情况符合条件,多种,一种和不可能分别输出三种情况
思路:刚读完题根本没有思路,看了网上的才知道用网络流,那样的话就好办了,建个源点,与每行建一条流量为行和的边,每一列与汇点建一条流量为列和的边,每行与每列建一条流量为9的边,跑最大流后判断是否满流就行了,但是要怎么判断有没有多组解呢,当残余网络中有环时,我们可以调整这个环来符合条件,将一条边加1,则另一条边可以减去1,所以判断残余网络中有没有大于2的环,并不会......,看大多数题解都是dfs回溯时删边或者删点,并不会,然后我的做法是将可行的边先预处理出来,然后非常暴力的dfs,一不小心400ms过了.......
#include <queue>#include <vector>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>#include <functional>using namespace std;typedef long long ll;const int inf=0x3f3f3f3f;const int maxn=1010;struct edge{ int to,cap,rev; edge(int a,int b,int c){to=a;cap=b;rev=c;}};vector<edge>G[maxn];vector<int>G1[maxn];int level[maxn],iter[maxn],vis[maxn],n,m;void addedge(int from,int to,int cap){ G[from].push_back(edge(to,cap,G[to].size())); G[to].push_back(edge(from,0,G[from].size()-1));}void add_edge(int from,int to){ G1[from].push_back(to);}void bfs(int s){ memset(level,-1,sizeof(level)); queue<int>que;level[s]=0; que.push(s); while(!que.empty()){ int v=que.front();que.pop(); for(unsigned int i=0;i<G[v].size();i++){ edge &e=G[v][i]; if(e.cap>0&&level[e.to]<0){ level[e.to]=level[v]+1; que.push(e.to); } } }}int dfs(int v,int t,int f){ if(v==t) return f; for(int &i=iter[v];i<G[v].size();i++){ edge &e=G[v][i]; if(e.cap>0&&level[v]<level[e.to]){ int d=dfs(e.to,t,min(f,e.cap)); if(d>0){ e.cap-=d; G[e.to][e.rev].cap+=d; return d; } } } return 0;}int max_flow(int s,int t){ int flow=0; while(1){ bfs(s); if(level[t]<0) return flow; memset(iter,0,sizeof(iter)); int f; while((f=dfs(s,t,inf))>0) flow+=f; }}bool Judge_dfs(int x,int val){ vis[x]=1; for(unsigned int i=0;i<G1[x].size();i++){ int t=G1[x][i]; if(t==val) continue; if(vis[t]) return 1; if(Judge_dfs(t,x)) return 1; } vis[x]=0; return 0;}bool judge(){ memset(vis,0,sizeof(vis)); for(int i=0;i<=n+m+1;i++){ for(unsigned int j=0;j<G[i].size();j++){ edge &e=G[i][j]; if(e.cap>0) add_edge(i,e.to); } } for(int i=0;i<=n;i++){ if(Judge_dfs(i,-1)) return 1; } return 0;}int main(){ int T,a,b,t=1; scanf("%d",&T); while(T--){ for(int i=0;i<maxn;i++){ G[i].clear(); G1[i].clear(); } scanf("%d%d",&n,&m); int sum=0,sum1=0,sum2=0; for(int i=1;i<=n;i++){ scanf("%d",&a);sum+=a;sum1+=a; addedge(0,i,a); } for(int j=1;j<=m;j++){ scanf("%d",&b);sum2+=b; addedge(j+n,n+m+1,b); } if(sum1!=sum2){ printf("Case #%d: So naive!\n",t++); continue; } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++) addedge(i,j+n,9); } int ans=max_flow(0,n+m+1); if(ans!=sum) printf("Case #%d: So naive!\n",t++); else{ if(judge()) printf("Case #%d: So young!\n",t++); else printf("Case #%d: So simple!\n",t++); } } return 0;}
0 0
- HDU 4975 最大流+判断环
- hdu 4975 最大流及其唯一性判定(有向图环判断算法升级)
- hdu 3572 最大流判断满流
- hdu 4888 Redraw Beautiful Drawings(Dinic最大流+判断有没有环)
- HDU 1853 Cyclic Tour (最小费用最大流+环的判断)
- HDU 2883 kebab【最大流】(判断是否满流)
- HDU Redraw Beautiful Drawings 判断最大流是否唯一解
- hdu 4888 Redraw Beautiful Drawings 最大流唯一性判断
- HDU 4888/4975 最大流
- HDU -- 4888 Redraw Beautiful Drawings(最大流,判断最大流唯一性)
- hdu 2444 (判断二分图+最大匹配)
- HDU 2444 判断二分图+最大匹配
- hdu 2444(二分图判断+最大匹配)
- HDU 2444 二分图判断+最大匹配
- hdu 4975 最大流快版
- HDU 3367 Pseudoforest 并查集求最大生成树及判断环
- HDU 4888 最大流+判环
- Hdu 3572 Task Schedule [最大流] 任务分配,判断满流
- Move Zeroes 带测试版
- test code浏览和IE操作FileSystemObject
- 记一次失败的kaggle比赛(1):赛题简介与初次尝试
- First Bad Version 带测试版
- iOS开发之自定义UITableView
- HDU 4975 最大流+判断环
- RecyclerView
- systemctl 命令完全指南
- hadoop基本操作
- Unable to add window -- token null is not for an application
- 全局变量的设置及注意事项
- Jmeter 转载
- Android中的WebService新解
- Palindrome Permutation 带测试版