zoukankan      html  css  js  c++  java
  • 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;
    }
                
    

  • 相关阅读:
    jython 访问数据库的方法
    Server 2008安装FTP的简单教程
    如何实现Android重启应用程序代码 ?
    android 应用程序自适应屏幕大小
    Android Dialog用法
    2008Server错误
    7种形式的Android Dialog使用举例
    ADB使用方法
    调用手机震动
    android小记之FTP文件上传
  • 原文地址:https://www.cnblogs.com/csnd/p/12063037.html
Copyright © 2011-2022 走看看