zoukankan      html  css  js  c++  java
  • kuangbin带我飞QAQ 最短路

     

    1. poj 1502 Mathches Game

      裸最短路

      1 #include <iostream>
      2 #include <string.h>
      3 #include <cstdio>
      4 #include <queue>
      5 #include <vector>
      6 #include <string>
      7 #include <cstring>
      8 #include <algorithm>
      9 #include <math.h>
     10 
     11 #define SIGMA_SIZE 26
     12 #pragma warning ( disable : 4996 )
     13 
     14 using namespace std;
     15 typedef long long LL;
     16 
     17 inline LL LMax(LL a,LL b)    { return a>b?a:b; }
     18 inline LL LMin(LL a,LL b)    { return a>b?b:a; }
     19 inline int Max(int a,int b) { return a>b?a:b; }
     20 inline int Min(int a,int b) { return a>b?b:a; }
     21 inline int gcd( int a, int b ) { return b==0?a:gcd(b,a%b); }
     22 inline int lcm( int a, int b ) { return a/gcd(a,b)*b; }  //a*b = gcd*lcm
     23 const long long INF = 0x3f3f3f3f3f3f3f3f;
     24 const int inf  = 0x3f3f3f3f;
     25 const int mod  = 7;
     26 const int maxk = 110;
     27 const int maxn = 110;
     28 
     29 struct edge {
     30     int to, next, val;
     31 }e[maxn*maxn];
     32 
     33 
     34 int dis[maxn], linjie[maxn];
     35 bool vis[maxn];
     36 int N, cnt, ans;
     37 
     38 void addedge( int x, int y, int val )
     39 {
     40     e[cnt].to = y; e[cnt].next = linjie[x]; e[cnt].val = val; linjie[x] = cnt++; }
     41 
     42 void init()
     43 {
     44     cnt = ans = 0;
     45     memset( linjie, -1, sizeof(linjie) );
     46     memset( dis, 0x3f, sizeof(dis) );
     47     memset( vis, 0, sizeof(vis) );
     48 }
     49 
     50 void read()
     51 {
     52     init();
     53     string str;
     54     int tmp = 1;
     55 
     56     for ( int i = 1; i < N; i++ )
     57     {
     58         for ( int j = 0; j < tmp; j++ )
     59         {
     60             int val = 0;
     61             cin >> str;
     62 
     63             if ( str == "x" )
     64                 continue;
     65             int len = str.length();
     66 
     67             int x = 1;
     68             for ( int k = len - 1; k >= 0; k-- )
     69             {
     70                 val += (str[k]-'0')*x;
     71                 x *= 10;
     72             }
     73             addedge( i, j, val );
     74             addedge( j, i, val );
     75         }
     76         tmp++;
     77     }
     78 }
     79 
     80 void dijkstra()
     81 {
     82     dis[0] = 0;
     83     
     84     for ( int i = 0; i < N; i++ )
     85     {
     86         int mindis = inf, mark = -1;
     87         for ( int j = 0; j < N; j++ )
     88             if ( !vis[j] && dis[j] < mindis )
     89             {
     90                 mark = j;
     91                 mindis = dis[j];
     92             }
     93 
     94         vis[mark] = true;
     95 
     96         for ( int j = linjie[mark]; j+1; j = e[j].next )
     97             if (!vis[e[j].to])
     98             {
     99                 int v = e[j].to, val = e[j].val;
    100                 dis[v] = Min(dis[v], dis[mark]+val);
    101             }
    102     }
    103 }
    104 
    105 int main()
    106 {
    107     cin >> N;
    108 
    109     read();
    110     dijkstra();
    111 
    112     for ( int i = 0; i < N; i++ )
    113         ans = Max( ans, dis[i] );
    114 
    115     cout << ans << endl;
    116     return 0;
    117 }
    View Code

    2. poj 3660 cow contest

      floyd 求传递闭包

     1 #include <iostream>
     2 #include <string.h>
     3 #include <cstdio>
     4 #include <queue>
     5 #include <vector>
     6 #include <string>
     7 #include <cstring>
     8 #include <algorithm>
     9 #include <math.h>
    10 
    11 #define SIGMA_SIZE 26
    12 #pragma warning ( disable : 4996 )
    13 
    14 using namespace std;
    15 typedef long long LL;
    16 
    17 inline LL LMax(LL a,LL b)    { return a>b?a:b; }
    18 inline LL LMin(LL a,LL b)    { return a>b?b:a; }
    19 inline int Max(int a,int b) { return a>b?a:b; }
    20 inline int Min(int a,int b) { return a>b?b:a; }
    21 inline int gcd( int a, int b ) { return b==0?a:gcd(b,a%b); }
    22 inline int lcm( int a, int b ) { return a/gcd(a,b)*b; }  //a*b = gcd*lcm
    23 const long long INF = 0x3f3f3f3f3f3f3f3f;
    24 const int inf  = 0x3f3f3f3f;
    25 const int mod  = 7;
    26 const int maxk = 110;
    27 const int maxn = 110;
    28 
    29 bool mmap[maxn][maxn];
    30 int ojbk[maxn];
    31 int N, M;
    32 
    33 void floyd()
    34 {
    35     for ( int k = 1; k <= N; k++ )
    36         for ( int i = 1; i <= N; i++ )
    37             for ( int j = 1; j <= N; j++ )
    38             {
    39                 mmap[i][j] = (mmap[i][j] || (mmap[i][k] && mmap[k][j]));
    40             }
    41 }
    42 
    43 int main()
    44 {
    45     cin >> N >> M;
    46 
    47     int x, y;
    48     for ( int i = 1; i <= M; i++ ) 
    49     {
    50         scanf("%d %d", &x, &y);
    51         mmap[x][y] = 1;
    52     }
    53 
    54     floyd();
    55 
    56     int ans = 0;
    57     for ( int i = 1; i <= N; i++ )
    58         for ( int j = 1; j <= N; j++ )
    59             if ( mmap[i][j] )
    60             {
    61                 ojbk[i]++;
    62                 ojbk[j]++;
    63             }
    64 
    65     for ( int i = 1; i <= N; i++ )
    66         if ( ojbk[i] == N-1 )
    67             ans++;
    68     cout << ans << endl;
    69 
    70     return 0;
    71 }
    View Code

    3. poj 1511 Invitation Cards

      双向最短路,正着求一次,边取反再求一次

      1 #include <iostream>
      2 #include <string.h>
      3 #include <cstdio>
      4 #include <queue>
      5 #include <map>
      6 #include <vector>
      7 #include <string>
      8 #include <cstring>
      9 #include <algorithm>
     10 #include <math.h>
     11 
     12 #define SIGMA_SIZE 26
     13 #pragma warning ( disable : 4996 )
     14 
     15 using namespace std;
     16 typedef long long LL;
     17 
     18 inline LL LMax(LL a,LL b)    { return a>b?a:b; }
     19 inline LL LMin(LL a,LL b)    { return a>b?b:a; }
     20 inline int Max(int a,int b) { return a>b?a:b; }
     21 inline int Min(int a,int b) { return a>b?b:a; }
     22 inline int gcd( int a, int b ) { return b==0?a:gcd(b,a%b); }
     23 inline int lcm( int a, int b ) { return a/gcd(a,b)*b; }  //a*b = gcd*lcm
     24 const long long INF = 0x3f3f3f3f3f3f3f3f;
     25 const int inf  = 0x3f3f3f3f;
     26 const int mod  = 7;
     27 const int maxk = 110;
     28 const int maxn = 1e6+5;
     29 
     30 int num[3*maxn];
     31 int linjie[maxn];
     32 int dis[maxn];
     33 bool vis[maxn];
     34 int P, Q, cnt;
     35 long long ans;
     36 
     37 struct edge {
     38     int to, next, val ;
     39 }e[maxn];
     40 
     41 struct cmp {
     42     bool operator() ( const int a, const int b )
     43         { return dis[a]>dis[b]; }
     44 };
     45 
     46 void addedge( int u, int v, int val )
     47 { e[cnt].to = v; e[cnt].next = linjie[u]; e[cnt].val = val; linjie[u] = cnt++; }    
     48 
     49 void init()
     50 {
     51     cnt = 0; ans = 0;
     52     memset( linjie, -1, sizeof(linjie) );
     53 }
     54 
     55 void dijkstra()
     56 {
     57     memset( dis, 0x3f, sizeof(dis) );
     58     memset( vis, 0, sizeof(vis) );
     59 
     60     priority_queue<int, vector<int>, cmp> q;
     61     dis[1] = 0;
     62     q.push(1);
     63 
     64     while (!q.empty())
     65     {
     66         int run = q.top(); q.pop();
     67         int mindis = dis[run];
     68 
     69         vis[run] = true;
     70 
     71         for ( int i = linjie[run]; i+1; i = e[i].next )
     72             if ( !vis[e[i].to] && dis[e[i].to] >  mindis + e[i].val )
     73             {
     74                 dis[e[i].to] =  mindis + e[i].val;
     75                 q.push(e[i].to);
     76             }
     77     }
     78     for ( int i = 2; i <= P; i++ )
     79         ans += (long long)dis[i];
     80 }
     81 
     82 int main()
     83 {
     84     int n;
     85     cin >> n;
     86 
     87     while (n--)
     88     {
     89         init();
     90         scanf( "%d %d", &P, &Q );
     91 
     92         int j = 1;
     93         for ( int i = 1; i <= Q; i++ )
     94         {
     95             scanf( "%d %d %d", &num[j], &num[j+1], &num[j+2] );
     96             addedge( num[j], num[j+1], num[j+2] );
     97             j += 3;
     98         }
     99         dijkstra();
    100         
    101         //重新建边///
    102         memset( linjie, -1, sizeof(linjie) );
    103         cnt = 0; j = 1;
    104         for ( int i = 1; i <= Q; i++ )
    105         {
    106             addedge( num[j+1], num[j], num[j+2] );
    107             j += 3;
    108         }
    109 
    110         dijkstra();
    111 
    112         printf( "%lld
    ", ans );
    113     }
    114 
    115     return 0;
    116 }
    View Code

    4.poj 3159 Candies

      dijsktra+优先队列优化+差分约束

      1 #include <iostream>  
      2 #include <string.h>  
      3 #include <stdio.h>  
      4 #include <algorithm>  
      5 #include <queue>  
      6 #include <vector>  
      7 #define SIGMA_SIZE 26
      8 #pragma warning ( disable : 4996 )
      9 
     10 using namespace std;
     11 typedef long long LL;
     12 
     13 inline LL LMax(LL a,LL b)    { return a>b?a:b; }
     14 inline LL LMin(LL a,LL b)    { return a>b?b:a; }
     15 inline int Max(int a,int b) { return a>b?a:b; }
     16 inline int Min(int a,int b) { return a>b?b:a; }
     17 inline int gcd( int a, int b ) { return b==0?a:gcd(b,a%b); }
     18 inline int lcm( int a, int b ) { return a/gcd(a,b)*b; }  //a*b = gcd*lcm
     19 const long long INF = 0x3f3f3f3f3f3f3f3f;
     20 const int inf  = 0x3f3f3f3f;
     21 const int mod  = 7;
     22 const int maxk = 200000 + 5;
     23 const int maxn = 50000 + 5;
     24 
     25 int linjie[maxn];
     26 int dis[maxn];
     27 bool vis[maxn];
     28 int P, Q, cnt;
     29 
     30 struct qnode
     31 {
     32     int v;
     33     int c;
     34     qnode(int _v=0,int _c=0):v(_v),c(_c){}
     35     bool operator <(const qnode &r)const
     36     {
     37         return c>r.c;
     38     }
     39 };
     40 
     41 struct edge {
     42     int to, next, val ;
     43 }e[maxk];
     44 
     45 void addedge( int u, int v, int val )
     46 { e[cnt].to = v; e[cnt].next = linjie[u]; e[cnt].val = val; linjie[u] = cnt++; }    
     47 
     48 void init()
     49 {
     50     cnt = 0;
     51     memset( linjie, -1, sizeof(linjie) );
     52 }
     53 
     54 void dijkstra()
     55 {
     56     memset( dis, 0x3f, sizeof(dis) );
     57     memset( vis, 0, sizeof(vis) );
     58 
     59     priority_queue<qnode> q;
     60     while(!q.empty()) q.pop();
     61     dis[1] = 0;
     62     q.push(qnode(1,0));
     63 
     64     qnode tmp;
     65 
     66     while (!q.empty())
     67     {
     68         tmp = q.top(); q.pop();
     69         int run = tmp.v;
     70         int mindis = dis[run];
     71 
     72         vis[run] = true;
     73 
     74         for ( int i = linjie[run]; i+1; i = e[i].next )
     75             if ( !vis[e[i].to] && dis[e[i].to] >  mindis + e[i].val )
     76             {
     77                 int v = e[i].to;
     78                 dis[v] =  mindis + e[i].val;
     79                 q.push(qnode(v, dis[v]));
     80             }
     81     }
     82 }
     83 
     84 int main()
     85 {
     86     init();
     87     scanf( "%d%d", &P, &Q );
     88 
     89         
     90     int x, y, z;
     91     for ( int i = 1; i <= Q; i++ )
     92     {
     93         scanf( "%d%d%d", &x, &y, &z );
     94         addedge(x,y,z);
     95     }
     96 
     97     dijkstra();
     98 
     99     printf( "%d
    ", dis[P] );
    100 
    101     return 0;
    102 }
    View Code

    5. poj 3169 Layout

      spfa+负环+差分约束

      最经典的差分约束,因为求的是dis[N]-dis[1]的最大值 ,即dis[N]-dis[1] <= x,所以用最短路。用spfa判断若有负环,说明最短路无限小,所以无解;若dis[N] = inf,说明最短路可以无限大,

      1 #include <iostream>
      2 #include <string.h>
      3 #include <cstdio>
      4 #include <queue>
      5 #include <map>
      6 #include <vector>
      7 #include <string>
      8 #include <cstring>
      9 #include <algorithm>
     10 #include <math.h>
     11 
     12 #define SIGMA_SIZE 26
     13 #pragma warning ( disable : 4996 )
     14 
     15 using namespace std;
     16 typedef long long LL;
     17 
     18 inline LL LMax(LL a,LL b)    { return a>b?a:b; }
     19 inline LL LMin(LL a,LL b)    { return a>b?b:a; }
     20 inline int Max(int a,int b) { return a>b?a:b; }
     21 inline int Min(int a,int b) { return a>b?b:a; }
     22 inline int gcd( int a, int b ) { return b==0?a:gcd(b,a%b); }
     23 inline int lcm( int a, int b ) { return a/gcd(a,b)*b; }  //a*b = gcd*lcm
     24 const long long INF = 0x3f3f3f3f3f3f3f3f;
     25 const int inf  = 0x3f3f3f3f;
     26 const int mod  = 7;
     27 const int maxk = 2e4+5;
     28 const int maxn = 1010;
     29 
     30 int N, Ml, Md, cnt;
     31 int linjie[maxn], in[maxn];
     32 bool vis[maxn];
     33 long long dis[maxn];
     34 
     35 struct edge {
     36     int to, next, val;
     37 }e[maxk];
     38 
     39 void addedge( int u, int v, int val )
     40 {
     41     e[cnt].to = v;
     42     e[cnt].next = linjie[u];
     43     e[cnt].val = val;
     44     linjie[u] = cnt++;
     45 }
     46 
     47 void init()
     48 {
     49     cnt = 0;
     50     memset( linjie, -1, sizeof(linjie) );
     51 }
     52 
     53 long long spfa()
     54 {
     55     memset( dis, 0x3f, sizeof(dis) );
     56 
     57     queue<int> q;
     58     q.push(1); dis[1] = 0;
     59 
     60     while ( !q.empty() )
     61     {
     62         int run = q.front(); q.pop();
     63         vis[run] = false;
     64 
     65         for ( int i = linjie[run]; i+1; i = e[i].next )
     66         {
     67             int v = e[i].to, cost = e[i].val;
     68             if ( dis[v] > dis[run] + cost )
     69             {
     70                 dis[v] = dis[run] + cost;
     71                 if (!vis[v])
     72                 {
     73                     in[v]++;
     74                     if ( in[v] > N ) return -1;
     75 
     76                     vis[v] = true; 
     77                     q.push(v); 
     78                 }
     79             }
     80         }
     81     }
     82 
     83     if ( dis[N] == INF ) return -2;
     84     else
     85         return dis[N];
     86 }
     87 
     88 int main()
     89 {
     90     init();
     91     cin >> N >> Ml >> Md;
     92 
     93     //差分约束条件建边
     94     int a, b, z;
     95     for ( int i = 1; i <= Ml; i++ )
     96         { scanf("%d%d%d", &a, &b, &z); addedge(a,b,z); }
     97     for ( int i = 1; i <= Md; i++ )
     98         { scanf("%d%d%d", &a, &b, &z); addedge(b,a,-z); }
     99 
    100     printf( "%lld
    ", spfa() );
    101     return 0;
    102 }
    View Code

    6. hdu3416 Marriage Match IV

      dijkstra+最大流dinic当前弧优化

      hdu的题好难...这题最不一样的是求一共有多少条最短路(路径不可以重复),一个暴力的想法就是求一条最短路再删去该路的所有边,再求最短路,再删边,直到求得最短路长度大于第一次求得的长度为止,不过用脚趾头想都知道数据肯定会卡你的。

    其实会发现如果抛弃最短路来看,这道题很像最大流,就是所有边权为1求最大流的题目,不过现在加了约束条件必须在最短路上取最大流。所以我们可以求出所有的最短路径的边并重新建一个边权为1的图,在其上做最大流就可以了,那么怎么求所有最短路径呢?

    有个方法是从终点dijkstra一下再从起点dijkstra下(注意要建立反向边图),假设dis1[u]表示start-u之间最短距离,dis2[v]表示v-end之间最短距离,那么只要dis1[u]+dis2[v]+dis[u][v] == 最短路长度,就代表这条边是可以要的

      1 #include <iostream>
      2 #include <string.h>
      3 #include <cstdio>
      4 #include <queue>
      5 #include <map>
      6 #include <vector>
      7 #include <string>
      8 #include <cstring>
      9 #include <algorithm>
     10 #include <math.h>
     11 
     12 #define SIGMA_SIZE 26
     13 #pragma warning ( disable : 4996 )
     14 
     15 using namespace std;
     16 typedef long long LL;
     17 
     18 inline LL LMax(LL a,LL b)    { return a>b?a:b; }
     19 inline LL LMin(LL a,LL b)    { return a>b?b:a; }
     20 inline int Max(int a,int b) { return a>b?a:b; }
     21 inline int Min(int a,int b) { return a>b?b:a; }
     22 inline int gcd( int a, int b ) { return b==0?a:gcd(b,a%b); }
     23 inline int lcm( int a, int b ) { return a/gcd(a,b)*b; }  //a*b = gcd*lcm
     24 const long long INF = 0x3f3f3f3f3f3f3f3f;
     25 const int inf  = 0x3f3f3f3f;
     26 const int mod  = 7;
     27 const int maxk = 1e5+5;
     28 const int maxn = 1010;
     29 
     30 int N, M, cnt;
     31 int st, ed;
     32 int num[maxk*3];
     33 int disst[maxn], dised[maxn], cur[maxn];
     34 int linjie1[maxn], linjie2[maxn];
     35 bool vis[maxn];
     36 
     37 struct node {
     38     int to, next, val;
     39 }e1[maxk], e2[maxk];
     40 
     41 void addedge1( int u, int v, int val )
     42 { e1[cnt].to = v; e1[cnt].val = val; e1[cnt].next = linjie1[u]; linjie1[u] = cnt++; }
     43 void addedge2( int u, int v, int val )
     44 { e2[cnt].to = v; e2[cnt].val = val; e2[cnt].next = linjie2[u]; linjie2[u] = cnt++; }
     45 
     46 void init()
     47 {
     48     cnt = 0;
     49     memset( linjie1, -1, sizeof(linjie1) );
     50     memset( linjie2, -1, sizeof(linjie2) );
     51 }
     52 
     53 void dijkstra( int x )
     54 {
     55     memset( vis, 0, sizeof(vis) );
     56     memset( disst, 0x3f, sizeof(disst) );
     57     disst[x] = 0;
     58 
     59     for ( int k = 1; k <= N; k++ )
     60     {
     61         int mark = -1, mindis = inf;
     62         for ( int i = 1; i <= N; i++ )
     63             if ( !vis[i] && disst[i] < mindis )
     64             {
     65                 mark = i;
     66                 mindis = disst[i];
     67             }
     68         vis[mark] = true;
     69 
     70         for ( int i = linjie1[mark]; i+1; i = e1[i].next )
     71         {
     72             int v = e1[i].to, cost = e1[i].val;
     73             if ( !vis[v] && disst[v] > disst[mark] + cost )
     74                 disst[v] = disst[mark] + cost;
     75         }
     76     }
     77 }
     78 
     79 void make_map()
     80 {
     81     cnt = 0;
     82     int mindist = disst[ed];
     83 
     84     for ( int i = 1; i <= N; i++ )
     85         for ( int j = linjie1[i]; j + 1; j = e1[j].next )
     86         {
     87             int v = e1[j].to, cost = e1[j].val;
     88             if ( disst[i] + cost + dised[v] == mindist )
     89                 addedge2( i, v, 1 );
     90         }
     91 }
     92 
     93 int bfs()
     94 {
     95     memset( disst, -1, sizeof(disst) );
     96     queue<int> q;
     97 
     98     q.push(st);
     99     disst[st] = 0;
    100 
    101     while( !q.empty() )
    102     {
    103         int run = q.front(); q.pop();
    104         for( int i = linjie2[run]; i+1; i = e2[i].next )
    105         {
    106             int v = e2[i].to, flow = e2[i].val;
    107             if( disst[v] < 0 && flow > 0 )
    108             {
    109                 disst[v] = disst[run] + 1;
    110                 q.push(v);
    111             }
    112         }
    113     }
    114 
    115     if( disst[ed] > 0 )
    116         return 1;
    117     else
    118         return 0;
    119 }
    120 
    121 int find( int s, int low )
    122 {
    123     int ff = 0;
    124     if( s == ed )
    125         return low;
    126     for( int& i = cur[s]; i+1; i = e2[i].next )    //注意int& i = cur[s] 当前弧优化
    127     {
    128         int v = e2[i].to, cap = e2[i].val;
    129         if( cap > 0
    130             && disst[v] == disst[s] + 1
    131             && (ff = find(v,Min(cap,low))) )
    132         {
    133             e2[i].val -= ff;
    134             //e2[i^1].val += ff;
    135             return ff;
    136         }
    137     }
    138     return 0;
    139 }
    140 
    141 int dinic()
    142 {
    143     int ans = 0;
    144     int tans;
    145     while( bfs() )
    146     {
    147         for( int i = 1; i <= N; i++ )   //当前弧优化
    148             cur[i] = linjie2[i];
    149         while( tans = find( st, inf ) )
    150             ans += tans;
    151     }
    152     return ans;
    153 }
    154 
    155 
    156 int main()
    157 {
    158     int T; cin >> T;
    159     while (T--)
    160     {
    161         scanf("%d%d", &N, &M);
    162         
    163         init();
    164         for (int i = 1, j = 1; i <= M; i++)
    165         {
    166             scanf( "%d%d%d", &num[j], &num[j+1], &num[j+2] );
    167             addedge1(num[j+1],num[j],num[j+2]);
    168             j += 3;
    169         }
    170 
    171         scanf("%d%d", &st, &ed);
    172 
    173         dijkstra(ed);
    174         for ( int i = 1; i <= N; i++ )
    175             dised[i] = disst[i];
    176         cnt = 0;
    177         memset( linjie1, -1, sizeof(linjie1) );
    178         for ( int i = 1, j = 1; i <= M; i++ )
    179         {
    180             addedge1( num[j], num[j+1], num[j+2] );
    181             j += 3;
    182         }
    183         dijkstra(st);
    184         make_map();
    185 
    186         printf( "%d
    ", dinic() );
    187     }
    188     return 0;
    189 }
    View Code
  • 相关阅读:
    POJ 1330 Nearest Common Ancestors(LCA Tarjan算法)
    LCA 最近公共祖先 (模板)
    线段树,最大值查询位置
    带权并查集
    转负二进制
    UVA 11437 Triangle Fun
    UVA 11488 Hyper Prefix Sets (字典树)
    UVALive 3295 Counting Triangles
    POJ 2752 Seek the Name, Seek the Fame (KMP)
    UVA 11584 Partitioning by Palindromes (字符串区间dp)
  • 原文地址:https://www.cnblogs.com/chaoswr/p/8946732.html
Copyright © 2011-2022 走看看