SGU 242 Student's Morning 网络流(水
2016-03-06 08:33
591 查看
题目链接:点击打开链接
题意:
给定n个人,m个终点
以下n行表示每一个人能够去m个点。
每一个人仅仅能去一个点。
输出随意一个方案使得每一个点至少有2个人到达。
若存在输出m行,第一个数字表示i这个点来了几个人,后面是人的点标。
思路:
建一个二部图n-m,然后m到汇点限流2。推断是否满流,若不满流就无解。
若满流则其它的人随便走。
题意:
给定n个人,m个终点
以下n行表示每一个人能够去m个点。
每一个人仅仅能去一个点。
输出随意一个方案使得每一个点至少有2个人到达。
若存在输出m行,第一个数字表示i这个点来了几个人,后面是人的点标。
思路:
建一个二部图n-m,然后m到汇点限流2。推断是否满流,若不满流就无解。
若满流则其它的人随便走。
#include <stdio.h> #include <string.h> #include <iostream> #include <math.h> #include <queue> #include <set> #include <algorithm> using namespace std; typedef int ll; #define N 420 #define M 100000 #define inf 107374182 struct Edge{ ll from, to, cap, nex; }edge[M*2]; ll head , edgenum; void add(ll u, ll v, ll cap, ll rw = 0){ Edge E = {u, v, cap, head[u]}; edge[edgenum] = E; head[u] = edgenum ++; Edge E2 = {v, u, rw, head[v]}; edge[edgenum] = E2; head[v] = edgenum ++; } ll sign ; bool BFS(ll from, ll to){ memset(sign, -1, sizeof sign); sign[from] = 0; queue<ll>q; q.push(from); while( !q.empty() ) { ll u = q.front(); q.pop(); for(ll i = head[u]; ~i; i = edge[i].nex) { ll v = edge[i].to; if(sign[v] == -1 && edge[i].cap){ sign[v] = sign[u] +1, q.push(v); if(sign[to] != -1) return true; } } } return false; } ll Stack , top, cur ; ll Dinic(ll from, ll to){ ll ans = 0; while( BFS(from, to) ) { memcpy(cur, head, sizeof head); ll u = from; top = 0; while(1) { if(u==to) { ll flow = inf, loc; for(ll i = 0; i < top; i++) if(flow > edge[Stack[i]].cap) { flow = edge[Stack[i]].cap; loc = i; } for(ll i = 0; i < top; i++) { edge[ Stack[i] ].cap -= flow; edge[Stack[i]^1].cap += flow; } ans += flow; top = loc; u = edge[Stack[top]].from; } for(ll i = cur[u]; ~i; cur[u] = i = edge[i].nex) if(edge[i].cap && (sign[u]+1 == sign[edge[i].to]))break; if(cur[u] != -1){ Stack[top++] = cur[u]; u = edge[cur[u]].to; } else { if(top==0)break; sign[u] = -1; u = edge[Stack[--top]].from; } } } return ans; } void init(){memset(head, -1, sizeof head); edgenum = 0;} int n, m, from, to, to2, ans , G ; vector<int>D ; bool solve(){ from = 0; to = n+m+1; to2 = to+1; init(); for(int i = 1; i <= n; i++) { G[i] = -1; add(from, i, 1); int x, y; scanf("%d",&x); while(x--){ scanf("%d",&y); G[i] = y; add(i, n+y, 1); } } for(int i = 1; i <= m; i++) add(n+i, to, 2); add(to, to2, inf); if(m*2 > n || Dinic(from, to2) < m*2)return false; puts("YES"); for(int i = 1; i <= n; i++) { ans[i] = -1; for(int j = head[i]; ~j; j = edge[j].nex) { if(edge[j].cap==0 && edge[j].to != from) { ans[i] = edge[j].to-n; D[edge[j].to-n].push_back(i); break; } } if(ans[i]==-1 && G[i]!=-1) D[G[i]].push_back(i); } for(int i = 1; i <= m; i++) { printf("%d", D[i].size()); for(int j = 0; j < D[i].size(); j++) printf(" %d", D[i][j]); puts(""); } return true; } int main(){ while(~scanf("%d %d",&n,&m)){ if(solve()==false)puts("NO"); for(int i = 1; i <= m; i++)D[i].clear(); } return 0; } /* 5 2 1 1 1 2 1 1 1 1 1 1 5 2 1 1 1 2 1 1 1 1 2 1 2 */
相关文章推荐
- Android笔记---使用HttpClient发送POST和GET请求
- 网络存储实验基础
- ASIHttpRequest或者SDWebImage给UIImageView加载图片的逻辑是什么样子的
- Linux学习笔记:Xshell连接VMware网络连接问题
- HttpLuaModule——翻译(Nginx API for Lua) (转)
- 实现一个同步的迭代型TCP服务器
- BZOJ2756/SCOI2012 奇怪的游戏
- HDU 5639 Deletion 二分+网络流
- android stuido 报 If you are behind an HTTP proxy, please configure the proxy set
- TCP/IP网络协议之DHCP简介
- iOS网络判断
- hadoop使用javaAPI实现hdfs常见操作(转载于http://www.cnblogs.com/xuqiang/archive/2011/06/03/2042526.html)
- 一个http请求的详细过程
- Linux 网络编程 套接字结构
- 关于”TCP直接返回“
- Fiddler(三)- Fiddler命令行和HTTP断点调试
- iOS 开发 之 网络编程
- CentOS系统安装完毕后,网络连接方式为NAT,系统无法上网或IP设置成静态后无法上
- 最详细的 HTTPS 科普扫盲帖
- TCP/IP基础(五)