洛谷 - P4001 [ICPC-Beijing 2006]狼抓兔子(网格图最大流转换为对偶图最短路)
题目链接:点击查看
题目大意:给出一张 n * m 的稠密图,求以点 ( 1 , 1 ) 为起点,点 ( n , m ) 为终点的最小割
题目分析:n 和 m 都是 1e3 级别的,最多可能有 1e6 个点,3e6 条边,跑最大流显然是正确的,但是时间复杂度肯定是顶不住的,正确做法应该是将其转换为对偶图然后跑最短路,注意建边是无向边
讲解博客:https://www.cnblogs.com/jinkun113/p/9495308.html
我的建图方法是先将每个点预处理标号,下面图中红色是原来的点,蓝色是对偶图中的点
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=2e6+100;//顶点数 const int M=6e6+100;//边数 struct Edge
{int to,w,next;
}edge[M];int head[N],d[N],cnt,n,m,id[1100][1100][2];//链式前向星 bool vis[N];void addedge(int u,int v,int w)
{edge[cnt].to=v;edge[cnt].w=w;edge[cnt].next=head[u];head[u]=cnt++;edge[cnt].to=u;edge[cnt].w=w;edge[cnt].next=head[v];head[v]=cnt++;
}struct Node
{int to,w;Node(int TO,int W){to=TO;w=W;}bool operator<(const Node& a)const{return w>a.w;}
};void Dijkstra(int st)
{priority_queue<Node>q;memset(vis,false,sizeof(vis));memset(d,inf,sizeof(d));d[st]=0;q.push(Node(st,0));while(q.size()){Node cur=q.top();int u=cur.to;q.pop();if(vis[u])continue;vis[u]=true;for(int i=head[u];i!=-1;i=edge[i].next)//扫描出所有边 {int v=edge[i].to;int w=edge[i].w;if(d[v]>d[u]+w)//更新 {d[v]=d[u]+w;q.push(Node(v,d[v]));}}}
}void init()
{memset(head,-1,sizeof(head));cnt=0;int tot=0;for(int i=1;i<n;i++)for(int j=1;j<m;j++){id[i][j][0]=++tot;id[i][j][1]=++tot;}
}int main()
{
#ifndef ONLINE_JUDGE
// freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif
// ios::sync_with_stdio(false);scanf("%d%d",&n,&m);init();int st=N-1,ed=st-1;for(int i=1;i<=n;i++)//横边 for(int j=1;j<m;j++){int w;scanf("%d",&w);if(i==1)addedge(id[1][j][0],ed,w);else if(i==n)addedge(st,id[n-1][j][1],w);elseaddedge(id[i][j][0],id[i-1][j][1],w); }for(int i=1;i<n;i++)//竖边 for(int j=1;j<=m;j++){int w;scanf("%d",&w);if(j==1)addedge(st,id[i][1][1],w);else if(j==m)addedge(id[i][m-1][0],ed,w);elseaddedge(id[i][j-1][0],id[i][j][1],w);}for(int i=1;i<n;i++)for(int j=1;j<m;j++){int w;scanf("%d",&w);addedge(id[i][j][1],id[i][j][0],w);}Dijkstra(st);printf("%d\n",d[ed]);return 0;
}
洛谷 - P4001 [ICPC-Beijing 2006]狼抓兔子(网格图最大流转换为对偶图最短路)相关推荐
- 【洛谷4001】 [ICPC-Beijing 2006]狼抓兔子(最小割)
传送门 洛谷 Solution 直接跑最小割板子就好了. 代码实现 #include<stdio.h> #include<stdlib.h> #include<strin ...
- 洛谷 P4001 [ICPC-Beijing 2006]狼抓兔子
题目描述 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: ...
- P4001 [ICPC-Beijing 2006]狼抓兔子(ISAP模板题)
传送门 题目描述 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的 ...
- P4001-[ICPC-Beijing 2006]狼抓兔子【对偶图】
正题 题目链接:https://www.luogu.com.cn/problem/P4001 题目大意 给出一个类似于 的网格图,求起点到终点的最小割. 解题思路 最小割直接跑网络流,然后发现dini ...
- 1001: [BeiJing2006]狼抓兔子
/**************************************************************Problem: 1001User: whymheLanguage: C+ ...
- 狼抓兔子(平面图转对偶图)
狼抓兔子(平面图转对偶图) 面对下面这样一个网格的地形: 道路上的权值表示这条路上最多能够通过的兔子数,道路是无向的. 左上角和右下角为兔子的两个窝,开始时所有的兔子都聚集在左上角(1,1)的窝里,现 ...
- BZOJ 1001: [BeiJing2006]狼抓兔子【最大流/SPFA+最小割,多解】
1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec Memory Limit: 162 MB Submit: 23822 Solved: 6012 [Submit ...
- BZOJ1001 狼抓兔子 终于过了!
时间来不及了,先贴代码吧!有时间再写. 好苦逼啊,WA了若干次,还有一次RE,一次TLE. 虽然主要运用的算法和资料都由师兄提供了.还是太弱了,太天真了. 首先,数据范围就WA了,RE了,TLE了. ...
- 1001: [BeiJing2006]狼抓兔子(对偶图)
1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec Memory Limit: 162 MB Submit: 23595 Solved: 5940 Descrip ...
最新文章
- 【工具方法util】JAVA中将一个List等分成n个list的
- opencv 计时 帧率
- 禁用viewstate怎么还保存状态?
- 微信小程序开发教程(基础篇)8-数据绑定下
- 开源docker轻量级管理平台shipyard部署(中文版)
- java中对集合操作的易错点01
- 盘点《令人心动的offer》中让人敲黑板的重点
- Linux中的文件权限
- APP完整的启动流程
- jsp需要多少java基础_Java Web基础面试题你知道多少?
- 苹果Mac超轻量级菜单栏应用程序:Micro Snitch
- 【云周刊】第200期:云栖专辑 | 阿里开发者们的第6个感悟:享受折磨
- java POI导出excel性能优化
- 1、【QT】QT6.2 官网下载与安装教程
- 龙芯3A3000编译安装Postgresql12.2
- 品质担当,有效提升办公生产力,永艺XY人体工学椅开箱实测
- 客单价怎么算 影响客单价的主要因素有哪些?
- solid works定义样条曲线
- 四级英语口语模拟测试软件,2018年大学英语四级口语考试模拟
- 商品货架管理(愿疫情早日消散,大家去见想见的人)