Sentry Robots UVA
来源:互联网 发布:投资组合经理 知乎 编辑:程序博客网 时间:2024/05/17 10:41
题目链接:点击打开链接
题目大意:懒得说了
题目思路:看题目的的问法,我们很容易想到是最小点覆盖或者边覆盖的问题,我们可以发现对于某个重要的点(x,y),只用x,y其中一个点备选中就行,是不是发现了,就是最小点覆盖的定义:求最小数量的点,使得包括每条边的至少一个端点,所以,我们对于每一个重要位置的左边,根据行列建图,从x联向y,容量为1,然后求最小点覆盖,但是这里还有一个地方就是会有障碍点,那么我们可以先把每一行的坐标离散化,如果这一行有障碍,我们就加一,列的同理。。。
ac代码:
#include<cstdio>#include<queue>#include<iostream>#include<sstream>#include<map>#include<cstring>#define LL long long#define INF 0x3f3f3f3fusing namespace std;const int inf = 0x3f3f3f3f;const int MX = 200+5;const int MXE = 5 * MX * MX;int T;int n,m;int cnt1;int cnt2;int mp[105][105];int r[105][105];int c[105][105];struct MaxFlow{ struct Edge { int v, w, nxt; } edge[MXE],edge2[MXE]; int tot, num, s, t; int head[MX]; void init() { memset(head, -1, sizeof(head)); tot = 0; } void add(int u, int v, int w) { edge[tot].v = v; edge[tot].w = w; edge[tot].nxt = head[u]; head[u] = tot++; edge[tot].v = u; edge[tot].w = 0; edge[tot].nxt = head[v]; head[v] = tot++; } int d[MX], vis[MX], gap[MX]; void bfs() { memset(d, 0, sizeof(d)); memset(gap, 0, sizeof(gap)); memset(vis, 0, sizeof(vis)); queue<int>q; q.push(t); vis[t] = 1; while (!q.empty()) { int u = q.front(); q.pop(); for (int i = head[u]; ~i; i = edge[i].nxt) { int v = edge[i].v; if (!vis[v]) { d[v] = d[u] + 1; gap[d[v]]++; q.push(v); vis[v] = 1; } } } } int last[MX]; int dfs(int u, int f) { if (u == t) return f; int sap = 0; for (int i = last[u]; ~i; i = edge[i].nxt) { int v = edge[i].v; if (edge[i].w > 0 && d[u] == d[v] + 1) { last[u] = i; int tmp = dfs(v, min(f - sap, edge[i].w)); edge[i].w -= tmp; edge[i ^ 1].w += tmp; sap += tmp; if (sap == f) return sap; } } if (d[s] >= num) return sap; if (!(--gap[d[u]])) d[s] = num; ++gap[++d[u]]; last[u] = head[u]; return sap; } int solve(int st, int ed, int n) { int flow = 0; num = n; s = st; t = ed; bfs(); memcpy(last, head, sizeof(head)); while (d[s] < num) flow += dfs(s, inf); return flow; }} F;int main(){ scanf("%d",&T); while(T--){ F.init(); memset(r,0,sizeof(r)); memset(c,0,sizeof(c)); memset(mp,0,sizeof(mp)); scanf("%d%d",&n,&m); scanf("%d",&cnt1); for(int i = 0;i<cnt1;i++){ int x,y; scanf("%d%d",&x,&y); mp[x][y] = 1; } scanf("%d",&cnt2); for(int i = 0;i<cnt2;i++){ int x,y; scanf("%d%d",&x,&y); mp[x][y] = 2; } int N = 0; for(int i = 1;i<=m;i++){ int ok = 1; for(int j = 1;j<=n;j++){ if(mp[j][i]==1){ if(ok) N++; r[j][i] = N; ok = 0; } else if(mp[j][i] == 2){ ok = 1; } } } int M = 0; for(int i = 1;i<=n;i++){ int ok = 1; for(int j = 1;j<=m;j++){ if(mp[i][j]==1){ if(ok) M++; c[i][j] = M+N; ok = 0; } else if(mp[i][j]==2){ ok = 1; } } } for(int i = 1;i<=n;i++){ for(int j= 1;j<=m;j++){ if(mp[i][j] == 1){ F.add(r[i][j],c[i][j],1); } } } int NN = N; int MM = M; N = M = 0; for(int i = 1;i<=m;i++){ int ok = 1; for(int j = 1;j<=n;j++){ if(mp[j][i]==1){ if(ok){ N++; F.add(NN+MM+1,N,1); } r[j][i] = N; ok = 0; } else if(mp[j][i] == 2){ ok = 1; } } } for(int i = 1;i<=n;i++){ int ok = 1; for(int j = 1;j<=m;j++){ if(mp[i][j]==1){ if(ok){ M++; F.add(M+N,NN+MM+2,1); } c[i][j] = M+N; ok = 0; } else if(mp[i][j]==2){ ok = 1; } } } //cout<<N<<' '<<M<<endl; int ans = F.solve(NN+MM+1,NN+MM+2,NN+MM+2); cout<<ans<<endl; }}
阅读全文
0 0
- Sentry Robots UVA
- Sentry Robots UVA
- UVA 12549(p381)----Sentry Robots
- uva 12549 Sentry Robots 最大二分匹配
- Sentry Robots
- UVA 12549 Sentry Robots 最小点集覆盖
- Uva 12549 Sentry Robots 网络流 - 二分图匹配
- UVAlive 6156 Sentry Robots
- 【uva 12549】Sentry Robots HDU 2119 (hdu 2119Matrix升级版) 最小点覆盖+二分图匹配
- 12549 - Sentry Robots (二分图匹配)
- Sentry Robots, ACM/ICPC SWERC 2012, UVa12549 【二分图】
- uva 10599 Robots(II)
- UVA 10599 Robots(II)
- UVA - 10599 Robots(II)
- uva 10599 Robots(II)
- uva 10599 - Robots(II)
- UVA - 10599 Robots(II)
- uva 10599 Robots(II)
- 斯坦福机器学习笔记 第1周 一、引言(Introduction)
- 多线程爬虫爬取电影天堂资源
- 网络判断—NetWorkUtil
- 【网站抓取】如何正确识别Baiduspider移动ua
- 实现并行抓取整站40万条房价数据(可更换抓取城市)
- Sentry Robots UVA
- 300. Longest Increasing Subsequence
- ogg格式文件转换为MP3格式
- 抓取妹子图
- 用 construct 2 制作 html 小游戏
- 如何使用makefile编译不同平台的目标文件(makefile的参数传递)
- 爬虫之模拟登录总结
- 安卓里,对fragment的粗略认识与总结
- Java中equals()与==区别