• hdu3870 基于最短路的最小割


    题意:
         给你一个平面图,让你输出(1,1),(n ,n)的最小割..


    思路:
          看完题想都没想直接最大流,结果TLE,想想也是 G<400*400,400*400*4>,这样的图超时不冤枉,后来在网上看了题解,都说是什么论文题目,果断去看论文结果没看懂,后来看了下别人的理解,自己再画画图大概知道是什么意思了,果断是看着没有证明的证明容易懂啊..


     把最小割转换成最短路是有限制条件的,就是这个图首先必须是平面图,然后要求的这两个点还必须是平面图最外侧的点,给你图解就明白了,感觉文字的东西越说越蒙..




    看看上面的图就明白了吧,首先我们的目的就是要把s和t断开,也就是找一条横向的最短路径把他们切断,又因为路径的长度是根据容量来建的,所以最短路就是最小割..好想法...

    #include<stdio.h>
    #include<string.h>
    #include<queue>
    
    #define N_node 165000
    #define N_edge 700000
    #define INF 1000000000
    
    using namespace std;
    
    typedef struct
    {
       int to ,cost ,next;
    }STAR;
    
    STAR E[N_edge];
    int list[N_node] ,tot;
    int s_x[N_node];
    int map[405][405];
    
    void add(int a, int b ,int c)
    {
       E[++tot].to = b;
       E[tot].cost = c;
       E[tot].next = list[a];
       list[a] = tot;
       
       E[++tot].to = a;
       E[tot].cost = c;
       E[tot].next = list[b];
       list[b] = tot;
    }
    
    void SPFA(int s ,int n)
    {
       for(int i = 0 ;i <= n ;i ++)
       s_x[i] = INF;
       int mark[N_node] = {0};
       mark[s] = 1;
       s_x[s] = 0;
       queue<int>q;
       q.push(s);
       while(!q.empty())
       {
          int tou ,xin;
          tou = q.front();
          q.pop();
          mark[tou] = 0;
          for(int k = list[tou] ;k ;k = E[k].next)
          {
             xin = E[k].to;
             if(s_x[xin] > s_x[tou] + E[k].cost)
             {
                s_x[xin] = s_x[tou] + E[k].cost;
                if(!mark[xin])
                {
                   mark[xin] = 1;
                   q.push(xin);
                }
             }
          }
       }
       return ;
    }
    
    int main ()
    {
       int n ,i ,j ,t;
       scanf("%d" ,&t);
       while(t--)
       {
          scanf("%d" ,&n);
          for(i = 1 ;i <= n ;i ++)
          for(j = 1 ;j <= n ;j ++)
          scanf("%d" ,&map[i][j]);
          n--;
          int ss = 0 ,tt = n * n + 1;
          memset(list ,0 ,sizeof(list));
          tot = 1;
          for(i = 1 ;i <= n ;i ++)
          for(j = 1 ;j <= n ;j ++)
          {
             int now = (i - 1) * n + j;
             int to1 = (i - 1) * n + j + 1;
             int to2 = (i - 1) * n + j + n; 
             if(j != n) add(now ,to1 ,map[i][j+1]);
             if(i != n) add(now ,to2 ,map[i+1][j]);
             if(j == 1) add(ss ,now ,map[i][j]);
             if(i == n) add(ss ,now ,map[i+1][j]);
             if(j == n) add(now ,tt ,map[i][j+1]);
             if(i == 1) add(now ,tt ,map[i][j]);
          }
          SPFA(ss ,tt);
          printf("%d
    " ,s_x[tt]);
       }
       return 0;
    }
    

  • 相关阅读:
    Linux测试端口是否连通的方法 -bash: telnet: 未找到命令
    Numpy全面学习资料
    python中调用java代码
    JDK的安装及环境变量配置
    python中logging模块的一些简单用法
    python得到代码所在文件的绝对路径
    Linux重定向(输入输出重定向)详解
    linux中grep命令的用法
    pyquery CSS选择器兄弟元素
    pyquery CSS选择器父级元素
  • 原文地址:https://www.cnblogs.com/csnd/p/12063151.html
Copyright © 2020-2023  润新知