0
点赞
收藏
分享

微信扫一扫

hdu3035 最小割转换成最短路

题意:
      给你一个平面图,要求从求出从左上角到右下角的最小割。
思路:

      如果大意的可能直接上来一遍最大流,然后就会各种悲剧的MLE,TLE,其实这个题目可以用到有个论文里面的那个平面图最小割转最短路(hdu3870 也是这种问题),我们证明说着费劲直接给一个图片理解就行了,思路就是这张图片

hdu3035 最小割转换成最短路_最小割


这个题目用Spfa会超时的,要用优化过的Dij才能过,我不会的优化过的Dij,直接用模板过的。


#include<stdio.h>
#include<string.h>
#include<queue>

using namespace std;

//*************************************************
#include<queue>
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define clr(f,z) memset(f,z,sizeof(f))
#define LL long long
using namespace std;

const int mm=1e6+9;
const LL oo=1e16;
class Edge
{
public:int v,next;LL w;
};
class Dot
{
public:LL dis;int v;
Dot(){}
Dot(int _v,LL _d)
{
v=_v;dis=_d;
}
bool operator<(const Dot&x)const
{
return dis>x.dis;
}
};
class ShortPath
{
public:
int head[mm],edge;Edge e[3000000];
void clear()
{
clr(head,-1);edge=0;
}
void add(int u,int v,LL w)
{
e[edge].v=v;e[edge].w=w;e[edge].next=head[u];head[u]=edge++;
}
bool vis[mm];int id[mm];LL dis[mm];
priority_queue<Dot>Q;
LL dijstra(int s,int t,int n)
{
int u,v;Dot uu;
FOR(i,0,n)dis[i]=oo,vis[i]=0;
Q.push(Dot(s,0));dis[s]=0;
while(!Q.empty())
{
uu=Q.top();Q.pop();u=uu.v;
if(vis[u])continue;vis[u]=1;
for(int i=head[u];~i;i=e[i].next)
{ v=e[i].v;
if(!vis[v]&&dis[v]>dis[u]+e[i].w)
{
dis[v]=dis[u]+e[i].w;
Q.push(Dot(v,dis[v]));
}
}
}
return dis[t];
}
}sf;

//sf.clear();
//sf.add();
//sf.dijstra(s ,t ,n);
//********************************


int main ()
{
int n ,m ,i ,j ,a ,b ,now ,p1 ,p2 ,p3 ,p4;
while(~scanf("%d %d" ,&n ,&m))
{
int s = 0 ,t = n * m * 4 + 1;
sf.clear();
for(i = 1 ;i <= n + 1;i ++)
for(j = 1 ;j <= m ;j ++)
{
scanf("%d" ,&a);
now = (i - 1) * m + j;
p1 = (now - 1) * 4 + 1;
p2 = (now - 1) * 4 + 2;
p3 = (now - 1) * 4 + 3;
p4 = (now - 1) * 4 + 4;

if(i == 1) sf.add(s ,p2 ,a);
else if(i == n + 1)
{
int p44 = ((i - 1 - 1) * m + j - 1) * 4 + 4;
sf.add(p44 ,t ,a);
}
else
{
int noww = now - m;
sf.add(p2 ,(noww - 1) * 4 + 4 ,a);
sf.add((noww - 1) * 4 + 4 ,p2 ,a);
}
}

for(i = 1 ;i <= n ;i ++)
for(j = 1 ;j <= m + 1 ;j ++)
{
scanf("%d" ,&a);
now = (i - 1) * m + j;
p1 = (now - 1) * 4 + 1;
p2 = (now - 1) * 4 + 2;
p3 = (now - 1) * 4 + 3;
p4 = (now - 1) * 4 + 4;
if(j == 1) sf.add(p1 ,t ,a);
else if(j == m + 1)
{
int p33 = ((i - 1) * m + j - 1 - 1) * 4 + 3;
sf.add(s ,p33 ,a);
}
else
{
int noww = now - 1;
sf.add(p1 ,(noww - 1) * 4 + 3 ,a);
sf.add((noww - 1) * 4 + 3 ,p1 ,a);
}
}

for(i = 1 ;i <= n * 2 ;i ++)
for(j = 1 ;j <= m ;j ++)
{
scanf("%d %d" ,&a ,&b);
int ii = (i + 1) / 2;
now = (ii - 1) * m + j;
p1 = (now - 1) * 4 + 1;
p2 = (now - 1) * 4 + 2;
p3 = (now - 1) * 4 + 3;
p4 = (now - 1) * 4 + 4;
if(i & 1)
{
sf.add(p1 ,p2 ,a) ,sf.add(p2 ,p1 ,a);
sf.add(p2 ,p3 ,b) ,sf.add(p3 ,p2 ,b);
}
else
{
sf.add(p3 ,p4 ,b) ,sf.add(p4 ,p3 ,b);
sf.add(p4 ,p1 ,a) ,sf.add(p1 ,p4 ,a);
}
}
printf("%d\n" ,sf.dijstra(s ,t ,t));
}
return 0;
}




举报

相关推荐

0 条评论