zoukankan      html  css  js  c++  java
  • 【最大流】Sgu 185 _ Two shortest

    为了这题我都快wa傻了,简述几点

    1.鄙视卡内存的题目

    2.鄙视卡内存还卡时间的题目

    这题我本来是的思路是求一次最短路,删除这条路上的边,然后再求一次最短路,后来我举了一个例子,将这个方法否定掉了

    如果我们按照红色的路径删除最短路,就破坏了另一条最短路。

    因此我们换了一个思路,那就是求最大流。

    方法是:先求一次最短路,然后将最短路树上的每一条边都加入到一个新的图中,将流量设为1,费用就是边长,建立一个新的图,然后求两次最小费用最大流。

    理论上的基础是:

    1.最短路树上能到达终点的路径一定是最短路。

    2.所有边流量都是1,所以最大流一定不相交。

    View Code
      1 //sevenkplus bless me
      2 #include<iostream>
      3 #include<cstdio>
      4 #include<algorithm>
      5 #include<stdlib.h>
      6 #include<cctype>
      7 #include<cmath>
      8 #include<limits.h>
      9 #include<iomanip>
     10 #include<cstring>
     11 #include<fstream>
     12 #include<string>
     13 #include<queue>
     14 #include<stack>
     15 #include<set>
     16 #include<map>
     17 #include<vector>
     18 using namespace std;
     19 const double pi = 4.0 * atan(1.0);
     20 typedef signed long long LL;
     21 #define clr(x) memset(x,0,sizeof(x))
     22 #define clro(x) memset(x,-1,sizeof(x))
     23 typedef pair<int,int> pii;
     24 const int inf = 9999999;
     25 #define sf scanf
     26 #define pf printf
     27 const int maxn = 500;
     28 const int maxm = 160004;
     29 bool vis[maxn];
     30 int dis[maxn];
     31 int w[maxn][maxn];
     32 struct Edge{ short from,to,cap,len; };
     33 Edge edges[maxm];
     34 int head[maxn];
     35 int next[maxm];
     36 int pre[maxn];
     37 int tot,deep;
     38 queue<short>que;
     39 bool spfaa( short s,short t){
     40     int i;
     41     short u,v;
     42     if( t <= 2 ) return false;
     43     clr(vis);
     44     for( i=0; i<maxn; ++i) dis[i] = inf;
     45     dis[s] = 0;
     46     que.push(s);
     47     while( !que.empty() ){
     48         u = que.front(); que.pop();
     49         vis[u] = false;
     50         for( v=0; v<maxn; ++v){
     51             if( dis[u] + w[u][v] < dis[v] ){
     52                 dis[v] = w[u][v] + dis[u];
     53                 if( !vis[v] ){
     54                     vis[v] = true;
     55                     que.push(v);
     56                 }
     57             }
     58         }
     59     }
     60     if( dis[t] == inf ) return false;
     61     return true;
     62 }
     63 void addedge( short from, short to, int len){
     64     Edge z;
     65     z.from = from, z.to = to, z.cap = 1, z.len = len;
     66     edges[tot] = z;
     67     next[tot] = head[from];
     68     head[from] = tot++;
     69     z.from = to, z.to = from, z.cap = 0, z.len = len;
     70     edges[tot] = z;
     71     next[tot] = head[to];
     72     head[to] = tot++;
     73 }
     74 bool spfa( int s,int t){
     75     int i;
     76     clr(vis);
     77     queue<short>que;
     78     for( i=0; i<maxn; ++i) dis[i] = inf;
     79     dis[s] = 0;
     80     que.push(s);
     81     while( !que.empty() ){
     82         short u = que.front(); que.pop();
     83         vis[u] = false;
     84         for( i=head[u]; ~i; i = next[i]){
     85             Edge &e = edges[i];
     86             if( e.cap > 0 && dis[u] + e.len < dis[e.to] ){
     87                 pre[e.to] = i;
     88                 dis[e.to] = e.len+ dis[u];
     89                 if( !vis[e.to] ){
     90                     vis[e.to] = true;
     91                     que.push(e.to);
     92                 }
     93             }
     94         }
     95     }
     96     if( dis[t] == inf ) return false;
     97     return true;
     98 }
     99 int fl;
    100 int N;
    101 void dfs(int u, int f) {
    102     if (fl) return ;
    103     pre[u] = f;
    104     if (u == N) {
    105         fl = true;
    106         return ;
    107     }
    108     for (int i = head[u]; ~i; i = next[i]) {
    109         if (fl) return ;
    110         if ((i & 1) == 0 && edges[i].cap == 0) {
    111             edges[i].cap = -1;
    112             dfs(edges[i].to, u);
    113         }
    114     }
    115 
    116 }
    117 
    118 void print(int s, int t) {
    119     int rec[maxn];
    120     fl = false;
    121     dfs(s, -1);
    122     int k = 0;
    123     for (int u = t; ~u; u = pre[u]) {
    124         rec[k++] = u;
    125     }
    126     for (int i = k - 1; i >= 0; --i) {
    127         if (i < k - 1) putchar(' ');
    128         printf("%d", rec[i]);
    129     }
    130     printf("\n");
    131 }
    132 void path( int s, int t){
    133     for( int u = t; u != s; u = edges[pre[u] ].from){
    134         edges[pre[u] ].cap -= 1;
    135         edges[pre[u]^1 ].cap += 1;
    136     }
    137 }
    138 int maxflow( int s, int t){
    139     int f = 0;
    140     while( spfa(s,t) ){
    141         path(s,t);
    142         if( ++f ==  2 ) return f;
    143     }
    144     return f;
    145 }
    146 void init(){
    147     clro(head);
    148     for( int i=0; i<maxn; ++i)
    149         for( int j=0; j<maxn; ++j)
    150             w[i][j] = inf;
    151     tot = 0;
    152 }
    153 bool doit(int n, int m){
    154     N = n;
    155     int a,b,c;
    156     init();
    157     for( int i=0; i<m; ++i){
    158         sf("%d%d%d",&a,&b,&c);
    159         w[a][b] = min( w[a][b], c);
    160         w[b][a] = w[a][b];
    161     }
    162     if( !spfaa(1,n) ){
    163         puts("No solution");
    164         return false;
    165     }
    166     for( int i=0; i<maxn; ++i){
    167         for( int j=0; j<maxn; ++j){
    168             if( w[i][j] + dis[i] == dis[j] )
    169                 addedge(i,j,w[i][j]);
    170         }
    171     }
    172     return true;
    173 }
    174 int main(){
    175     int n,m;
    176     sf("%d%d",&n,&m);
    177     if( doit(n,m) ){
    178         //cout<<fff.maxflow(1,n)<<endl;
    179         if( maxflow(1,n) < 2 ){
    180             puts("No solution");
    181             return 0;
    182         }
    183     }
    184     print(1,n);
    185     print(1,n);
    186     return 0;
    187 }
  • 相关阅读:
    Python学习【第五篇】:面向对象及相关
    Python之路【第四篇】:模块
    Python之路【第三篇】:python基础(二)
    Python之路【第二篇】:Python基础(一)
    Python之路【第一篇】:Python简介和入门
    Open-source Tutorial
    Algorithms
    Mathematics Base
    Mathematics Base
    Open-source Tutorial
  • 原文地址:https://www.cnblogs.com/hewifi/p/2824296.html
Copyright © 2011-2022 走看看