zoj 3135 Party of 8g 最大点权独立集
2015-08-05 16:00
441 查看
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3165
题意:有M个男孩和N个女孩 他们每个人都有一个love值。
现在要邀请他们中的一部分人,满足他们之间没有“8g”关系。
给出M,N,S. S表示有S对boy和girl之间有“8g”关系。
思路:
最大点权独立集。
原图基础上增加源s和汇t。
s向每个boy连一条边,容量为这个人的love值。
每个girl向t连一条边,容量为这个人的love值。
然后每对"bg"关系boy向girl连一条边,容量为正无穷。
求最小割。答案 = 权值总和 - 最小割
再输出哪几个男孩和女孩被邀请了。
题意:有M个男孩和N个女孩 他们每个人都有一个love值。
现在要邀请他们中的一部分人,满足他们之间没有“8g”关系。
给出M,N,S. S表示有S对boy和girl之间有“8g”关系。
思路:
最大点权独立集。
原图基础上增加源s和汇t。
s向每个boy连一条边,容量为这个人的love值。
每个girl向t连一条边,容量为这个人的love值。
然后每对"bg"关系boy向girl连一条边,容量为正无穷。
求最小割。答案 = 权值总和 - 最小割
再输出哪几个男孩和女孩被邀请了。
#include <bits/stdc++.h> using namespace std; #define maxn 205 const int inf = 0x3f3f3f3f; struct Edge { int from, to, cap, flow; Edge(int f, int t, int c, int fl) { from = f; to = t; cap = c; flow = fl; } }; vector <Edge> edges; vector <int> G[maxn]; int vis[maxn], cur[maxn], d[maxn]; int s, t, n, m; void AddEdge(int from, int to, int cap) { edges.push_back(Edge(from, to, cap, 0)); edges.push_back(Edge(to, from, 0, 0)); m = edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } bool bfs() { memset(vis, 0, sizeof(vis)); d[s] = 0; vis[s] = 1; queue <int> q; q.push(s); while(!q.empty()) { int u = q.front(); q.pop(); for(int i = 0 ; i < G[u].size(); i++) { Edge &e = edges[G[u][i]]; if(!vis[e.to] && e.cap > e.flow) { d[e.to] = d[u]+1; vis[e.to] = 1; q.push(e.to); } } } return vis[t]; } int dfs(int x, int a) { if(x == t || a == 0) return a; int flow = 0, f; for(int &i = cur[x]; i < G[x].size(); i++) { Edge &e = edges[G[x][i]]; if(d[x] + 1 == d[e.to] && (f = dfs(e.to, min(a, e.cap - e.flow))) > 0) { e.flow += f; edges[G[x][i]^1].flow -= f; flow += f; a -= f; if(a == 0) break; } } return flow; } int Maxflow() { int flow = 0; while(bfs()) { memset(cur, 0, sizeof(cur)); flow += dfs(s, inf); } return flow; } int N, M, S; int b[110], g[110]; int main() { while(~scanf("%d%d%d", &M, &N, &S)) { edges.clear(); for(int i = 0; i <= N+M+1; i++) G[i].clear(); s = 0; t = N+M+1; int temp; int sum = 0; memset(b, 0, sizeof(b)); memset(g, 0, sizeof(g)); for(int i = 1; i <= M; i++) //BOY { scanf("%d", &temp); sum += temp; AddEdge(s, i, temp); } for(int i = 1; i <= N; i++) //GIRL { scanf("%d", &temp); sum += temp; AddEdge(i+M, t, temp); } for(int i = 1; i <= S; i++) { int a, b; scanf("%d%d", &a, &b); AddEdge(a, b+M, inf); } int flow = Maxflow(); sum -= flow; //cout<<sum<<endl; int cntb = 0, cntg = 0; for(int i = 0; i < m; i+=2) { if(edges[i].from == s) { if(vis[edges[i].to]) { b[edges[i].to] = 1; cntb++; } } if(edges[i].to == t) { if(!vis[edges[i].from]) { g[edges[i].from-M] = 1; cntg++; } } } printf("%d %d %d\n", sum, cntb, cntg); bool flag = true; for(int i = 1; i <= M; i++) { if(b[i]) { if(flag) printf("%d", i), flag = false; else printf(" %d",i); } } printf("\n"); flag = true; for(int i = 1; i <= N; i++) { if(g[i]) { if(flag) printf("%d", i), flag = false; else printf(" %d", i); } } printf("\n"); } return 0; }
相关文章推荐
- linux epoll事件模型详解(转载)
- 杭电acm 2504又见GCD
- DP ACdream 喵哈哈村的挑衅
- android 自定义ScrollView实现背景图片伸缩(阻尼效果)
- ios基础-字符串和数组的block遍历
- LeetCode之Binary Tree Inorder Traversal
- 使用php-java-bridge让PHP5支持java
- C#高级编程七十一天----DLR ScriptRuntime
- Hadoop集群(第9期)_MapReduce初级案例
- android 自定义ScrollView实现背景图片伸缩(阻尼效果)
- ListView,图片,两行内容
- opentsdb
- 程序人生成长发展中的一些感悟
- 关于相对路径
- C# 调用 C++ 写的Dll 遇到的问题(调用DLL 自动退出)
- go项目make
- Windows API CreateEvent函数用法
- eclipse+ EPIC + PadWalker 搭建Windows Perl开发环境
- 判断app是在前台还是后台
- Python中eval带来的潜在风险