BZOJ 1001 狼抓兔子 平面图最小割
2017-08-23 10:57
281 查看
题意:n*m地图 每个点可以走到其右边,下方,右下方.这3道路都有各自的流量限制.
源点s为左上角,终点t为右下角,
n,m<=1000,问最少需要多少个人堵住道路 使得s-t无路径存在.
堵住割上的边 则s-t无路径存在.花费最小也就是求最小割/最大流 n,m<=1e3 TLE...
本图是平面图,平面图的最小割等于其新图的最短路.
新图的点为原图的面.(建新图时对面合理的编号..)
新图边的权值等于:原图中分割这两个面的边的权值.
![](https://img-blog.csdn.net/20170823110045208?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbm9vbmUw/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> ii;
const int inf=0x3f3f3f3f;
const int N=4e6+20;
vector<ii> e
;
int s,t;
int n,m;
void add(int u,int v,int w)
{
e[u].push_back(ii(v,w));
e[v].push_back(ii(u,w));
}
bool inq
;
int dis
;
queue<int> q;
void SPFA(int s,int t)
{
memset(dis,inf,sizeof(dis));
memset(inq,0,sizeof(inq));
dis[s]=0,inq[s]=1,q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop(),inq[u]=0;
for(int i=0;i<e[u].size();i++)
{
int v=e[u][i].first,w=e[u][i].second;
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
if(!inq[v])
inq[v]=1,q.push(v);
}
}
}
cout<<dis[t]<<endl;
}
int main()
{
int k;
scanf("%d%d",&n,&m);
s=0,t=(n-1)*(m-1)*2+1;
//ho
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m-1;j++)
{
scanf("%d",&k);
if(i==1) add(j*2,t,k);
else if(i==n) add(s,(n-2)*(m-1)*2+j*2-1,k);
else add((i-2)*(m-1)*2+j*2-1,(i-1)*(m-1)*2+j*2,k);
// int u=(i-2)*(m-1)*2+j*2-1,v=(i-1)*(m-1)*2+j*2;
// cout<<i<<' '<<j<<' '<<u<<' '<<v<<endl;
}
}
//ver
for(int i=1;i<=n-1;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&k);
if (j==1) add((i-1)*(m-1)*2+1,0,k);
else if (j==m) add(t,i*(m-1)*2,k);
else add((i-1)*(m-1)*2+(j-1)*2,(i-1)*(m-1)*2+(j-1)*2+1,k);
}
}
for(int i=1;i<=n-1;i++)
{
for(int j=1;j<=m-1;j++)
{
scanf("%d",&k);
add((i-1)*(m-1)*2+j*2-1,(i-1)*(m-1)*2+j*2,k);
}
}
SPFA(s,t);
return 0;
}
源点s为左上角,终点t为右下角,
n,m<=1000,问最少需要多少个人堵住道路 使得s-t无路径存在.
堵住割上的边 则s-t无路径存在.花费最小也就是求最小割/最大流 n,m<=1e3 TLE...
本图是平面图,平面图的最小割等于其新图的最短路.
新图的点为原图的面.(建新图时对面合理的编号..)
新图边的权值等于:原图中分割这两个面的边的权值.
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> ii;
const int inf=0x3f3f3f3f;
const int N=4e6+20;
vector<ii> e
;
int s,t;
int n,m;
void add(int u,int v,int w)
{
e[u].push_back(ii(v,w));
e[v].push_back(ii(u,w));
}
bool inq
;
int dis
;
queue<int> q;
void SPFA(int s,int t)
{
memset(dis,inf,sizeof(dis));
memset(inq,0,sizeof(inq));
dis[s]=0,inq[s]=1,q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop(),inq[u]=0;
for(int i=0;i<e[u].size();i++)
{
int v=e[u][i].first,w=e[u][i].second;
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
if(!inq[v])
inq[v]=1,q.push(v);
}
}
}
cout<<dis[t]<<endl;
}
int main()
{
int k;
scanf("%d%d",&n,&m);
s=0,t=(n-1)*(m-1)*2+1;
//ho
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m-1;j++)
{
scanf("%d",&k);
if(i==1) add(j*2,t,k);
else if(i==n) add(s,(n-2)*(m-1)*2+j*2-1,k);
else add((i-2)*(m-1)*2+j*2-1,(i-1)*(m-1)*2+j*2,k);
// int u=(i-2)*(m-1)*2+j*2-1,v=(i-1)*(m-1)*2+j*2;
// cout<<i<<' '<<j<<' '<<u<<' '<<v<<endl;
}
}
//ver
for(int i=1;i<=n-1;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&k);
if (j==1) add((i-1)*(m-1)*2+1,0,k);
else if (j==m) add(t,i*(m-1)*2,k);
else add((i-1)*(m-1)*2+(j-1)*2,(i-1)*(m-1)*2+(j-1)*2+1,k);
}
}
for(int i=1;i<=n-1;i++)
{
for(int j=1;j<=m-1;j++)
{
scanf("%d",&k);
add((i-1)*(m-1)*2+j*2-1,(i-1)*(m-1)*2+j*2,k);
}
}
SPFA(s,t);
return 0;
}
相关文章推荐
- bzoj 1001: [BeiJing2006]狼抓兔子 平面图最小割
- BZOJ-1001 狼抓兔子 (最小割-最大流)平面图转对偶图+SPFA
- BZOJ-1001 狼抓兔子 (最小割-最大流)平面图转对偶图+SPFA
- BZOJ1001狼抓兔子(平面图最小割)
- BZOJ 1001 狼抓兔子 (网络流最小割/平面图的对偶图的最短路)
- BZOJ 1001 狼抓兔子 [最小割转最短路=平面图转对偶图]
- 【BZOJ1001】狼抓兔子(平面图转对偶图,最短路,最小割)
- bzoj1001 [BeiJing2006]狼抓兔子(最小割/平面图最大流转对偶图最短路)
- BZOJ 1001: [BeiJing2006]狼抓兔子(s-t平面图+最短路求最小割)
- 【平面图】【最小割】【最短路】【Heap-Dijkstra】bzoj1001 [BeiJing2006]狼抓兔子
- 【BZOJ1001】狼抓兔子,平面图转对偶图(从最小割到最短路)
- 【BZOJ1001】狼抓兔子(平面图最小割转最短路)
- BZOJ 1001: [BeiJing2006]狼抓兔子(平面图最小割转对偶图最短路)
- bzoj 1001 狼抓兔子 平面图最小割
- BZOJ_1001_狼抓兔子_(平面图求最小割+对偶图求最短路)
- 【BZOJ1001】狼抓兔子(BJOI2006)-平面图最小割转最短路
- 【BZOJ1001】【Beijing2006】狼抓兔子(平面图转对偶图:最小割+最短路)
- BZOJ1001 [BeiJing2006]狼抓兔子(平面图最小割转最短路)
- 狼抓兔子 BZOJ1001 平面图最小割转对偶图最短路
- 【BZOJ1001】【平面图最小割】狼抓兔子