【24.58%】【BZOJ 1001】狼抓兔子
来源:互联网 发布:光纤星型网络结构 编辑:程序博客网 时间:2024/06/08 18:09
Time Limit: 15 Sec Memory Limit: 162 MB
Submit: 19227 Solved: 4726
[Submit][Status][Discuss]
Description
现在小朋友们最喜欢的”喜羊羊与灰太狼”,话说灰太狼抓羊不到,但抓兔子还是比较在行的,
而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形:
左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类型的道路
1:(x,y)<==>(x+1,y)
2:(x,y)<==>(x,y+1)
3:(x,y)<==>(x+1,y+1)
道路上的权值表示这条路上最多能够通过的兔子数,道路是无向的. 左上角和右下角为兔子的两个窝,
开始时所有的兔子都聚集在左上角(1,1)的窝里,现在它们要跑到右下解(N,M)的窝中去,狼王开始伏击
这些兔子.当然为了保险起见,如果一条道路上最多通过的兔子数为K,狼王需要安排同样数量的K只狼,
才能完全封锁这条道路,你需要帮助狼王安排一个伏击方案,使得在将兔子一网打尽的前提下,参与的
狼的数量要最小。因为狼还要去找喜羊羊麻烦.
Input
第一行为N,M.表示网格的大小,N,M均小于等于1000.
接下来分三部分
第一部分共N行,每行M-1个数,表示横向道路的权值.
第二部分共N-1行,每行M个数,表示纵向道路的权值.
第三部分共N-1行,每行M-1个数,表示斜向道路的权值.
输入文件保证不超过10M
Output
输出一个整数,表示参与伏击的狼的最小数量.
Sample Input
3 4
5 6 4
4 3 1
7 5 3
5 6 7 8
8 7 6 5
5 5 5
6 6 6
Sample Output
14
HINT
2015.4.16新加数据一组,可能会卡掉从前可以过的程序。
【题目链接】:http://www.lydsy.com/JudgeOnline/problem.php?id=1001
【题解】
把整个图的对偶子图搞出来;
就是把所有线组成的面看成新的节点;
原来的线相邻的两个面之间连接一条边;边权就是原来的线的边权(容量);
如果原来的线没有相邻的面;就在那个面所代表的点连一条自环.
起点到终点的任意一条路径都是原图的一个割。
显然。咱们从起点到终点求一下最短路就是最小割了;
建对偶图可以按照下面的方法建;
其实就是从左到右,从上到下的顺序编号(每个大格);
然后编号乘个2,奇数就是上小格,偶数就是下小格。
盗张图
了解更多详见
http://wenku.baidu.com/link?url=87F10nBWauMdSF-PaKHoG-3fZj0jFE63P6pHSeX6ZiguQqXOQxm41iLWW5IdZCp2MWFQ8JghamfeI68PtLqEv_JSWapGp5z415gNoYb031u
【完整代码】
#include <cstdio>#include <iostream>#include <queue>#include <vector>#include <cstring>using namespace std;const int MAXN = 2000000;const int INF = 0x3f3f3f3f;int n,m,s,t;vector <int> a[MAXN];vector <int> w[MAXN];bool inque[MAXN];queue <int> dl;int dis[MAXN];void add(int x,int y,int z){ a[x].push_back(y); w[x].push_back(z); a[y].push_back(x); w[y].push_back(z);}int main(){ //freopen("F:\\rush.txt","r",stdin); scanf("%d%d",&n,&m); if (n==1 || m==1) { int mi = INF; for (int i = 1;i <= max(n,m)-1;i++) { int x; scanf("%d",&x); mi = min(mi,x); } printf("%d\n",mi); return 0; } s = 0; t = 2*(n-1)*(m-1)+1; for (int j = 1;j <= m-1;j++) { int cost; scanf("%d",&cost); int s1 = 2*j-1; add(s,s1,cost); } for (int i = 1;i <= n-2;i++) { for (int j = 1;j <= m-1;j++) { int cost; scanf("%d",&cost); int s1 = 2*((i-1)*(m-1)+j); int s2 = 2*(i*(m-1)+j)-1; add(s1,s2,cost); } } for (int j = 1;j <= m-1;j++) { int cost; scanf("%d",&cost); int s1 = 2*((n-2)*(m-1)+j); add(s1,t,cost); } //横边处理完毕.... for (int i = 1;i <= n-1;i++) { for (int j = 1;j <= m;j++) { int cost; cin >> cost; if (j==1) { int s1 = 2*((i-1)*(m-1)+1); add(s1,t,cost); } else if (j==m) { int s1 = 2*i*(m-1)-1; add(s,s1,cost); } else { int s1 = 2*((i-1)*(m-1)+j); int s2 = 2*((i-1)*(m-1)+j-1)-1; add(s1,s2,cost); } } } //竖边处理完毕.... for (int i = 1;i <= n-1;i ++) { for (int j = 1;j <= m-1;j++) { int cost; scanf("%d",&cost); int s1 = 2*((i-1)*(m-1)+j); int s2 = 2*((i-1)*(m-1)+j)-1; add(s1,s2,cost); } } //斜边处理完毕... memset(dis,INF,sizeof(dis)); dis[s] = 0; inque[s] = true; dl.push(s); while (!dl.empty()) { int x = dl.front(); inque[x] = false; dl.pop(); int len = a[x].size(); for (int i = 0;i <= len-1;i++) { int y = a[x][i]; int co = w[x][i]; if (dis[y] > dis[x]+co) { dis[y] = dis[x] + co; if (!inque[y]) { dl.push(y); inque[y] = true; } } } } printf("%d\n",dis[t]); return 0;}
- 【24.58%】【BZOJ 1001】狼抓兔子
- BZOJ 1001: 狼抓兔子
- [BZOJ 1001] 狼抓兔子
- BZOJ 1001 狼抓兔子
- BZOJ 1001 狼抓兔子
- [BZOJ 1001]狼抓兔子
- bzoj-1001 狼抓兔子
- [BZOJ 1001] 狼抓兔子
- bzoj 1001 狼抓兔子
- 【BZOJ】1001 狼抓兔子
- bzoj 1001狼抓兔子
- BZOJ 1001, 狼抓兔子
- BZOJ 1001 狼抓兔子
- BZOJ 1001 狼抓兔子
- bzoj 1001: [BeiJing2006]狼抓兔子
- BZOJ 1001: [BeiJing2006]狼抓兔子
- bzoj 1001: [BeiJing2006]狼抓兔子
- BZOJ 大视野 1001 狼抓兔子
- EventBus的使用
- 寻找sql注入的网站的方法
- PowerPC在信号处理中的应用
- ThreadLocal与Synchronized的使用
- Swift下多个Storyboard的项目结构
- 【24.58%】【BZOJ 1001】狼抓兔子
- 【JAVA基础】net.sf.json.JSONObject 和org.json.JSONObject 的差别
- 使用dd命令测试磁盘读写性能
- level 配合substr 和instr 进行字符串截取
- ctags一些命令
- IP地址与整形的相互转换原理 (Python实现)
- 怎么解决facbook被封禁的问题?
- block,inline和inline-block
- androidstudio调用jni实现日志打印