hdu3035 最小割转换成最短路

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

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



这个题目用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
" ,sf.dijstra(s ,t ,t));
   }
   return 0;
}
            

原文地址:https://www.cnblogs.com/csnd/p/12063037.html