• 双连通


    poj 3352 Road Construction && poj 3177 Redundant Paths

    给一个无向图,问最少需要添加多少条边,使它成为双连通图。

    做法:边双连通缩点,成为一棵树。若要使得任意一棵树,变成一个双连通图,那么至少增加的边数 =(度数为1的结点数 + 1 )/ 2

      1 #include<iostream>
      2 #include<cstring>
      3 #include<string>
      4 #include<cstdio>
      5 #include<stdio.h>
      6 #include<algorithm>
      7 #include<cmath>
      8 #include<set>
      9 #include<map>
     10 #include<queue>
     11 #include<bitset>
     12 
     13 using namespace std;
     14 
     15 
     16 #pragma comment(linker, "/STACK:1024000000,1024000000")
     17 #define inf 0x3f3f3f3f
     18 #define eps 1e-9
     19 #define FOR(i,s,t) for(int i = s; i < t; ++i )
     20 #define REP(i,s,t) for( int i = s; i <= t; ++i )
     21 #define pii pair<int,int>
     22 #define MP make_pair
     23 #define ls i << 1
     24 #define rs ls | 1
     25 #define md ((ll + rr) >> 1)
     26 #define lson ll, md, ls
     27 #define rson md + 1, rr, rs
     28 #define LL  long long
     29 #define N 1010
     30 #define M 2020
     31 #define Pi acos(-1.0)
     32 #define mod 1000007
     33 #define ULL unsigned long long
     34 
     35 int fst[N], nxt[M], vv[M], e;
     36 void init(){
     37     memset(fst, -1, sizeof fst); e = 0;
     38 }
     39 void add(int u, int v){
     40     vv[e] = v, nxt[e] = fst[u], fst[u] = e++;
     41 }
     42 
     43 int bccno[N], pre[N], dc, bcnt;
     44 bool cut[M];
     45 int dfs(int u, int p){
     46     int lowu = pre[u] = ++dc;
     47     for(int i = fst[u]; ~i; i = nxt[i]){
     48         int v = vv[i];
     49         if(!pre[v]){
     50             int lowv = dfs(v, u);
     51             lowu = min(lowu, lowv);
     52             if(lowv > pre[u]){
     53                 cut[i] = cut[i^1] = 1;
     54             }
     55         }
     56         else if(v != p)
     57             lowu = min(lowu, pre[v]);
     58     }
     59     return lowu;
     60 }
     61 void dfs2(int u, int cnt){
     62     bccno[u] = cnt;
     63     for(int i = fst[u]; ~i; i = nxt[i]){
     64         int v = vv[i];
     65         if(!bccno[v] && cut[i] == 0)
     66             dfs2(v, cnt);
     67     }
     68 }
     69 int in[N];
     70 int main(){
     71     int n, m;
     72     while(scanf("%d%d", &n, &m) != EOF){
     73         init();
     74         for(int i = 0; i < m; ++i){
     75             int u, v;
     76             scanf("%d%d", &u, &v);
     77             add(u, v), add(v, u);
     78         }
     79         dc = 0;
     80         memset(pre, 0, sizeof pre);
     81         memset(cut, 0, sizeof cut);
     82         dfs(1, -1);
     83         bcnt = 0;
     84         memset(bccno, 0, sizeof bccno);
     85         for(int i = 1; i <= n; ++i){
     86             if(!bccno[i])
     87                 dfs2(i, ++bcnt);
     88         }
     89         memset(in, 0, sizeof in);
     90         for(int i = 1; i <= n; ++i){
     91             for(int j = fst[i]; ~j; j = nxt[j]){
     92                 int v = vv[j];
     93                 if(bccno[i] == bccno[v]) continue;
     94                 in[bccno[i]]++, in[bccno[v]]++;
     95             }
     96         }
     97         int tot = 0;
     98         for(int i = 1; i <= bcnt; ++i){
     99             if(in[i] == 2) tot++;
    100         }
    101         printf("%d
    ", (tot+1)/2);
    102     }
    103     return 0;
    104 }
    View Code

    hdu 4738 Caocao's Bridges

    有n座岛和m条桥,每条桥上有w个兵守着,现在要派不少于守桥的士兵数的人去炸桥,只能炸一条桥,使得这n座岛不连通,求最少要派多少人去。

    做法:找权值最小的桥。有几个坑点:图不连通,输出0;有重边;桥上的士兵数为0,输出1。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<string>
      4 #include<cstdio>
      5 #include<stdio.h>
      6 #include<algorithm>
      7 #include<cmath>
      8 #include<set>
      9 #include<map>
     10 #include<queue>
     11 #include<bitset>
     12 
     13 using namespace std;
     14 
     15 
     16 #pragma comment(linker, "/STACK:1024000000,1024000000")
     17 #define inf 0x3f3f3f3f
     18 #define eps 1e-9
     19 #define FOR(i,s,t) for(int i = s; i < t; ++i )
     20 #define REP(i,s,t) for( int i = s; i <= t; ++i )
     21 #define pii pair<int,int>
     22 #define MP make_pair
     23 #define ls i << 1
     24 #define rs ls | 1
     25 #define md ((ll + rr) >> 1)
     26 #define lson ll, md, ls
     27 #define rson md + 1, rr, rs
     28 #define LL  long long
     29 #define N 1010
     30 #define M 2000020
     31 #define Pi acos(-1.0)
     32 #define mod 1000007
     33 #define ULL unsigned long long
     34 
     35 int fst[N], nxt[M], vv[M], cost[M], uu[M], num[N][N], e;
     36 void init(){
     37     memset(num, 0, sizeof num);
     38     memset(fst, -1, sizeof fst); e = 0;
     39 }
     40 void add(int u, int v, int c){
     41     uu[e] = u, vv[e] = v, nxt[e] = fst[u], cost[e] = c, fst[u] = e++;
     42 }
     43 
     44 int pre[N], bccno[N], dc, bcnt;
     45 bool cut[M];
     46 int dfs(int u, int p){
     47     int lowu = pre[u] = ++dc;
     48     for(int i = fst[u]; ~i; i = nxt[i]){
     49         int v = vv[i];
     50         if(!pre[v]){
     51             int lowv = dfs(v, u);
     52             lowu = min(lowu, lowv);
     53             if(lowv > pre[u])
     54                 cut[i] = cut[i^1] = 1;
     55         }
     56         else if(v != p)
     57             lowu = min(lowu, pre[v]);
     58     }
     59     return lowu;
     60 }
     61 void dfs2(int u, int cnt){
     62     bccno[u] = cnt;
     63     for(int i = fst[u]; ~i; i = nxt[i]){
     64         int v = vv[i];
     65         if(!bccno[v] &&cut[i] == 0)
     66             dfs2(v, cnt);
     67     }
     68 }
     69 int main(){
     70     int n, m;
     71     while(scanf("%d%d", &n, &m) != EOF){
     72         if(!n && !m) break;
     73         init();
     74         for(int i = 0; i < m; ++i){
     75             int u, v,  c;
     76             scanf("%d%d%d", &u, &v, &c);
     77             add(u, v, c);
     78             add(v, u, c);
     79             num[u][v]++, num[v][u]++;
     80         }
     81         dc = 0;
     82         memset(cut, 0, sizeof cut);
     83         memset(pre, 0, sizeof pre);
     84         dfs(1, -1);
     85         bool ok = 0;
     86         for(int i = 1; i <= n; ++i){
     87             if(!pre[i]) ok = 1;
     88         }
     89         if(ok){
     90             puts("0"); continue;
     91         }
     92         bcnt = 0;
     93         memset(bccno, 0, sizeof bccno);
     94         for(int i = 1; i <= n; ++i){
     95             if(!bccno[i])
     96                 dfs2(i, ++bcnt);
     97         }
     98         //printf("bcnt %d
    ", bcnt);
     99         if(bcnt == 1){
    100             puts("-1"); continue;
    101         }
    102         int ans = inf;
    103         for(int i = 0; i < e; i += 2){
    104             if(cut[i] && num[uu[i]][vv[i]] == 1)
    105                 ans = min(ans, cost[i]);
    106         }
    107         if(ans == 0) ans++;
    108         printf("%d
    ", ans);
    109     }
    110     return 0;
    111 }
    View Code

    poj 2942 Knights of the Round Table

    圆桌骑士。大白的题目。

    做法:点双连通。对每个连通分量判断是不是二分图。因为二分图是没有奇圈的。如果不能够染成二分图,则有奇圈,这个连通分量的人都是能够出席的。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<string>
      4 #include<cstdio>
      5 #include<stdio.h>
      6 #include<algorithm>
      7 #include<cmath>
      8 #include<vector>
      9 #include<stack>
     10 #include<queue>
     11 #include<bitset>
     12 using namespace std;
     13 
     14 
     15 #pragma comment(linker, "/STACK:1024000000,1024000000")
     16 #define inf 0x3f3f3f3f
     17 #define eps 1e-12
     18 #define FOR(i,s,t) for(int i = s; i < t; ++i )
     19 #define REP(i,s,t) for( int i = s; i <= t; ++i )
     20 #define pii pair<int,int>
     21 #define MP make_pair
     22 #define ls i << 1
     23 #define rs ls | 1
     24 #define md ((ll + rr) >> 1)
     25 #define lson ll, md, ls
     26 #define rson md + 1, rr, rs
     27 #define LL  long long
     28 #define N 1020
     29 #define M 2000020
     30 #define Pi acos(-1.0)
     31 #define mod 1000000007
     32 
     33 int fst[N], nxt[M], vv[M], e;
     34 void init(){
     35      memset(fst, -1, sizeof fst); e = 0;
     36 }
     37 void add(int u, int v){
     38     vv[e] = v, nxt[e] = fst[u], fst[u] = e++;
     39 }
     40 
     41 struct edge{
     42     int u, v;
     43     edge(int u = 0, int v = 0) : u(u), v(v) {}
     44 };
     45 stack<edge> E;
     46 vector<int> dcc[N];
     47 int pre[N], dccno[N], dc, dcnt;
     48 int dfs(int u, int p){
     49     int lowu = pre[u] = ++dc;
     50     for(int i = fst[u]; ~i; i = nxt[i]){
     51         int v = vv[i];
     52         edge e(u, v);
     53         if(!pre[v]){
     54             E.push(e);
     55             int lowv = dfs(v, u);
     56             lowu = min(lowv, lowu);
     57             if(lowv >= pre[u]){
     58                 dcnt++;
     59                 dcc[dcnt].clear();
     60                 while(1){
     61                     edge x = E.top(); E.pop();
     62                     if(dccno[x.u] != dcnt){
     63                         dcc[dcnt].push_back(x.u);
     64                         dccno[x.u] = dcnt;
     65                     }
     66                     if(dccno[x.v] != dcnt){
     67                         dcc[dcnt].push_back(x.v);
     68                         dccno[x.v] = dcnt;
     69                     }
     70                     if(x.u == u && x.v == v) break;
     71                 }
     72             }
     73         }
     74         else if(pre[v] < pre[u] && v != p)
     75             lowu = min(lowu, pre[v]);
     76     }
     77     return lowu;
     78 }
     79 
     80 int col[N], odd[N];
     81 bool bipartite(int u, int p, int b){
     82     for(int i = fst[u]; ~i; i = nxt[i]){
     83         int v = vv[i];
     84         if(v == p || dccno[v] != b) continue;
     85         if(col[v] == col[u]) return 0;
     86         if(!col[v]){
     87             col[v] = 3 - col[u];
     88             if(!bipartite(v, u, b)) return 0;
     89         }
     90     }
     91     return 1;
     92 }
     93 bool g[N][N];
     94 int main(){
     95     int n, m;
     96     while(scanf("%d%d", &n, &m) != EOF){
     97         if(!n && !m) break;
     98         memset(g, 0, sizeof g);
     99         for(int i = 0; i < m; ++i){
    100             int u, v;
    101             scanf("%d%d", &u, &v);
    102             g[u][v] = g[v][u] = 1;
    103         }
    104         init();
    105         for(int i = 1; i <= n; ++i){
    106             for(int j = i+1; j <= n; ++j){
    107                 if(!g[i][j]){
    108                     add(i, j), add(j, i);
    109                     g[i][j] = g[j][i] = 1;
    110                 }
    111             }
    112         }
    113         dc = dcnt = 0;
    114         memset(pre, 0, sizeof pre);
    115         memset(dccno, 0, sizeof dccno);
    116         for(int i = 1; i <= n; ++i){
    117             if(!pre[i]) dfs(i, -1);
    118         }
    119        // printf("dcnt %d
    ", dcnt);
    120         memset(odd, 0, sizeof odd);
    121         for(int i = 1; i <= dcnt; ++i){
    122             for(int j = 0; j < dcc[i].size(); ++j) dccno[dcc[i][j]] = i;
    123             memset(col, 0, sizeof col);
    124             int u = dcc[i][0];
    125             col[u] = 1;
    126             if(!bipartite(u, -1, i))
    127                 for(int j = 0; j < dcc[i].size(); ++j)
    128                     odd[dcc[i][j]] = 1;
    129         }
    130         int ans = n;
    131         for(int i = 1; i <= n; ++i)
    132             if(odd[i]) ans--;
    133         printf("%d
    ", ans);
    134     }
    135 }
    View Code

    hdu 3394 Railway

    题意:一个无向图,有 n 个景点,如果至少两个环公用一条路,路上的游客就会发生冲突;如果一条路不属于任何的环,这条路就没必要修。问,有多少路不必修,有多少路会发生冲突

    做法:没必要修的路就是桥。会发生冲突,则点双连通后,若连通分量里的边数大于点数,则这个连通分量里的路都是冲突边。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<string>
      4 #include<cstdio>
      5 #include<stdio.h>
      6 #include<algorithm>
      7 #include<cmath>
      8 #include<stack>
      9 #include<vector>
     10 #include<queue>
     11 #include<bitset>
     12 
     13 using namespace std;
     14 
     15 
     16 #pragma comment(linker, "/STACK:1024000000,1024000000")
     17 #define inf 0x3f3f3f3f
     18 #define eps 1e-9
     19 #define FOR(i,s,t) for(int i = s; i < t; ++i )
     20 #define REP(i,s,t) for( int i = s; i <= t; ++i )
     21 #define pii pair<int,int>
     22 #define MP make_pair
     23 #define ls i << 1
     24 #define rs ls | 1
     25 #define md ((ll + rr) >> 1)
     26 #define lson ll, md, ls
     27 #define rson md + 1, rr, rs
     28 #define LL  long long
     29 #define N 10010
     30 #define M 200020
     31 #define Pi acos(-1.0)
     32 #define mod 1000007
     33 #define ULL unsigned long long
     34 
     35 int fst[N], vv[M], nxt[M], e;
     36 void init(){
     37     memset(fst, -1, sizeof fst); e = 0;
     38 }
     39 void add(int u, int v){
     40     vv[e] = v, nxt[e] = fst[u], fst[u] = e++;
     41 }
     42 
     43 
     44 struct edge{
     45     int u, v;
     46     edge(int u = 0, int v = 0) : u(u), v(v) {}
     47 };
     48 stack<edge> E;
     49 vector<int> dcc[N];
     50 int dccno[N], pre[N], dc, dcnt, ans1, ans2;
     51 bool in[N];
     52 void calc(vector<int> &g){
     53     memset(in, 0, sizeof in);
     54     for(int i = 0; i < g.size(); ++i)
     55         in[g[i]] = 1;
     56     int tmp = 0;
     57     for(int i = 0; i < g.size(); ++i){
     58         int u = g[i];
     59         for(int j = fst[u]; ~j; j = nxt[j]){
     60             int v = vv[j];
     61             if(in[v])
     62                 tmp++;
     63         }
     64     }
     65     tmp /= 2;
     66     if(tmp > g.size())
     67         ans2 += tmp;
     68 }
     69 int dfs(int u, int p){
     70     int lowu = pre[u] = ++dc;
     71     for(int i = fst[u]; ~i; i = nxt[i]){
     72         int v = vv[i];
     73         edge e(u, v);
     74         if(!pre[v]){
     75             E.push(e);
     76             int lowv = dfs(v, u);
     77             lowu = min(lowv, lowu);
     78             if(lowv > pre[u])
     79                 ans1++;
     80             if(lowv >= pre[u]){
     81                 dcnt++;
     82                 dcc[dcnt].clear();
     83                 while(1){
     84                     edge x = E.top(); E.pop();
     85                     if(dccno[x.u] != dcnt){
     86                         dcc[dcnt].push_back(x.u);
     87                         dccno[x.u] = dcnt;
     88                     }
     89                     if(dccno[x.v] != dcnt){
     90                         dcc[dcnt].push_back(x.v);
     91                         dccno[x.v] = dcnt;
     92                     }
     93                     if(x.u == u && x.v == v) break;
     94                 }
     95                 calc(dcc[dcnt]);
     96             }
     97         }
     98         else if(pre[v] < pre[u] && v != p)
     99             lowu = min(lowu, pre[v]);
    100     }
    101     return lowu;
    102 }
    103 int main(){
    104     int n, m;
    105     while(scanf("%d%d", &n, &m) != EOF){
    106         if(!n && !m) break;
    107         init();
    108         for(int i = 0; i < m; ++i){
    109             int u, v;
    110             scanf("%d%d", &u, &v);
    111             add(u, v), add(v, u);
    112         }
    113         memset(dccno, 0, sizeof dccno);
    114         memset(pre, 0, sizeof pre);
    115         dc = dcnt = ans1 = ans2 = 0;
    116         for(int i = 0; i < n; ++i){
    117             if(!pre[i])
    118                 dfs(i, -1);
    119         }
    120         printf("%d %d
    ", ans1, ans2);
    121     }
    122     return 0;
    123 }
    View Code

    poj 1523 SPF

    找割顶。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<string>
      4 #include<cstdio>
      5 #include<stdio.h>
      6 #include<algorithm>
      7 #include<cmath>
      8 #include<vector>
      9 #include<stack>
     10 #include<queue>
     11 #include<bitset>
     12 using namespace std;
     13 
     14 
     15 #pragma comment(linker, "/STACK:1024000000,1024000000")
     16 #define inf 0x3f3f3f3f
     17 #define eps 1e-12
     18 #define FOR(i,s,t) for(int i = s; i < t; ++i )
     19 #define REP(i,s,t) for( int i = s; i <= t; ++i )
     20 #define pii pair<int,int>
     21 #define MP make_pair
     22 #define ls i << 1
     23 #define rs ls | 1
     24 #define md ((ll + rr) >> 1)
     25 #define lson ll, md, ls
     26 #define rson md + 1, rr, rs
     27 #define LL  long long
     28 #define N 1020
     29 #define M 2000020
     30 #define Pi acos(-1.0)
     31 #define mod 1000000007
     32 
     33 int fst[N], nxt[M], vv[M], e;
     34 void init(){
     35      memset(fst, -1, sizeof fst); e = 0;
     36 }
     37 void add(int u, int v){
     38     vv[e] = v, nxt[e] = fst[u], fst[u] = e++;
     39 }
     40 
     41 struct edge{
     42     int u, v;
     43     edge(int u = 0, int v = 0) : u(u), v(v) {}
     44 };
     45 stack<edge> E;
     46 vector<int> dcc[N];
     47 int pre[N], dccno[N], dc, dcnt;
     48 bool cut[N];
     49 int dfs(int u, int p){
     50     int lowu = pre[u] = ++dc;
     51     int son = 0;
     52     for(int i = fst[u]; ~i; i = nxt[i]){
     53         int v = vv[i];
     54         edge e(u, v);
     55         if(!pre[v]){
     56             E.push(e);
     57             son++;
     58             int lowv = dfs(v, u);
     59             lowu = min(lowu, lowv);
     60             if(lowv >= pre[u]){
     61                 cut[u] = 1;
     62                 ++dcnt;
     63                 dcc[dcnt].clear();
     64                 while(1){
     65                     edge x = E.top(); E.pop();
     66                     if(dccno[x.u] != dcnt){
     67                         dcc[dcnt].push_back(x.u);
     68                         dccno[x.u] = dcnt;
     69                     }
     70                     if(dccno[x.v] != dcnt){
     71                         dcc[dcnt].push_back(x.v);
     72                         dccno[x.v] = dcnt;
     73                     }
     74                     if(x.u == u && x.v == v) break;
     75                 }
     76             }
     77         }
     78         else if(pre[v] < pre[u] && v != p)
     79             lowu = min(lowu, pre[v]);
     80     }
     81     if(p < 0 && son == 1) cut[u] = 0;
     82     return lowu;
     83 }
     84 int num[N];
     85 int main(){
     86     int u, v, kk = 0;
     87     while(scanf("%d", &u) != EOF){
     88         if(u == 0) break;
     89         init();
     90         int n = u;
     91         while(1){
     92             scanf("%d", &v);
     93             n = max(n, v);
     94             add(u, v), add(v, u);
     95             scanf("%d", &u);
     96             n = max(n, u);
     97             if(u == 0) break;
     98         }
     99         memset(pre, 0, sizeof pre);
    100         memset(dccno, 0, sizeof dccno);
    101         memset(cut, 0, sizeof cut);
    102         dc = dcnt = 0;
    103         for(int i = 1; i <= n; ++i)
    104             if(!pre[i])
    105                 dfs(i, -1);
    106        // printf("dcnt %d
    ", dcnt);
    107         memset(num, 0, sizeof num);
    108         for(int i = 1; i <= dcnt; ++i){
    109             for(int j = 0; j < dcc[i].size(); ++j)
    110                 if(cut[dcc[i][j]])
    111                     num[dcc[i][j]]++;
    112         }
    113         printf("Network #%d
    ", ++kk);
    114         bool ok = 0;
    115         for(int i = 1; i <= n; ++i){
    116             if(cut[i]){
    117                 printf("  SPF node %d leaves %d subnets
    ", i, num[i]);
    118                 ok = 1;
    119             }
    120         }
    121         if(!ok)  puts("  No SPF nodes");
    122         puts("");
    123     }
    124 }
    View Code

    Gym 100338C Important Roads

    给一个无向图。若删除某些路径,则1到n的最短路会增加,则这些路径是important的。问哪些路径是important的。

    做法:对起点和终点分别求最短路,得到一定在最短路的边,然后双连通求桥。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<string>
      4 #include<cstdio>
      5 #include<stdio.h>
      6 #include<algorithm>
      7 #include<cmath>
      8 #include<stack>
      9 #include<vector>
     10 #include<queue>
     11 #include<bitset>
     12 
     13 using namespace std;
     14 
     15 
     16 #pragma comment(linker, "/STACK:1024000000,1024000000")
     17 #define inf 0x3f3f3f3f
     18 #define eps 1e-9
     19 #define FOR(i,s,t) for(int i = s; i < t; ++i )
     20 #define REP(i,s,t) for( int i = s; i <= t; ++i )
     21 #define pii pair<int,int>
     22 #define MP make_pair
     23 #define ls i << 1
     24 #define rs ls | 1
     25 #define md ((ll + rr) >> 1)
     26 #define lson ll, md, ls
     27 #define rson md + 1, rr, rs
     28 #define LL  long long
     29 #define N 20010
     30 #define M 200020
     31 #define Pi acos(-1.0)
     32 #define mod 1000007
     33 #define ULL unsigned long long
     34 
     35 int fst[N], vv[M], nxt[M], cost[M], e;
     36 void init(){
     37     memset(fst, -1, sizeof fst); e = 0;
     38 }
     39 void add(int u, int v, int c){
     40     vv[e] = v, nxt[e] = fst[u], cost[e] = c, fst[u] = e++;
     41 }
     42 
     43 struct edge{
     44     int v, id;
     45     edge(int v = 0, int id = 0) : v(v), id(id) {}
     46 };
     47 
     48 vector<edge> g[N];
     49 bool vis[N];
     50 int d[2][N];
     51 
     52 struct node{
     53     int u, dis;
     54     node(int u = 0, int dis = 0) : u(u), dis(dis) {}
     55     bool operator < (const node &b) const{
     56         return dis > b.dis;
     57     }
     58 };
     59 void dij(int s, int k){
     60     memset(vis, 0, sizeof vis);
     61     for(int i = 0; i < N; ++i)
     62         d[k][i] = (1LL<<31) - 1;
     63     priority_queue<node> q;
     64     q.push(node(s, 0));
     65     d[k][s] = 0;
     66     while(!q.empty()){
     67         node p = q.top(); q.pop();
     68         int u = p.u, dis = p.dis;
     69         if(vis[u]) continue;
     70         vis[u] = 1;
     71         for(int i = fst[u]; ~i; i = nxt[i]){
     72             int v = vv[i], c = cost[i];
     73             if(d[k][v] > d[k][u] + c){
     74                 d[k][v] = d[k][u] + c;
     75                 q.push(node(v, d[k][v]));
     76             }
     77         }
     78     }
     79 }
     80 int fa[N], id[N];
     81 void bfs(int s){
     82     queue<int> q;
     83     q.push(s);
     84     memset(fa, -1, sizeof fa);
     85     memset(vis, 0, sizeof vis);
     86     vis[s] = 1;
     87     while(!q.empty()){
     88         int u = q.front(); q.pop();
     89         for(int i = 0; i < g[u].size(); ++i){
     90             edge e = g[u][i];
     91             int v = e.v;
     92             if(!vis[v]){
     93                 fa[v] = u, id[v] = e.id;
     94                 vis[v] = 1;
     95                 q.push(v);
     96             }
     97         }
     98     }
     99 }
    100 int pre[N], dc, cut[M];
    101 int dfs(int u, int cot){
    102     int lowu = pre[u] = ++dc;
    103     for(int i = 0; i < g[u].size(); ++i){
    104         edge e = g[u][i];
    105         int v = e.v;
    106         if(!pre[v]){
    107             int lowv = dfs(v, e.id);
    108             lowu = min(lowu, lowv);
    109             if(lowv > pre[u])
    110                 cut[e.id] = 1;
    111         }
    112         else if(cot != e.id)
    113             lowu = min(lowu, pre[v]);
    114     }
    115     return lowu;
    116 }
    117 
    118 int main(){
    119 //    freopen("tt.txt", "r", stdin);
    120     freopen("important.in", "r", stdin);
    121     freopen("important.out", "w", stdout);
    122     int n, m;
    123     while(scanf("%d%d", &n, &m) != EOF){
    124         init();
    125         for(int i = 0; i < m; ++i){
    126             int u, v, c;
    127             scanf("%d%d%d", &u, &v, &c);
    128             add(u, v, c), add(v, u, c);
    129         }
    130         dij(1, 0);
    131         dij(n, 1);
    132         int tot = d[0][n];
    133         for(int i = 1; i <= n; ++i)
    134             g[i].clear();
    135         for(int i = 1; i <= n; ++i){
    136             for(int j = fst[i]; ~j; j = nxt[j]){
    137                 int u = i, v = vv[j], c = cost[j];
    138                 if(d[0][u] + c + d[1][v] == tot || d[0][v] + c + d[1][u] == tot){
    139                     g[u].push_back(edge(v, j / 2));
    140                     g[v].push_back(edge(u, j / 2));
    141                 }
    142             }
    143         }
    144         bfs(1);
    145         dc = 0;
    146         memset(cut, 0, sizeof cut);
    147         memset(pre, 0, sizeof pre);
    148         dfs(1, -1);
    149         int u = n;
    150         vector<int> ans;
    151         while(u != 1){
    152             if(cut[id[u]]) ans.push_back(id[u]+1);
    153             u = fa[u];
    154         }
    155         printf("%d
    ", ans.size());
    156         if(ans.size() == 0){
    157             puts(""); continue;
    158         }
    159         sort(ans.begin(), ans.end());
    160         for(int i = 0; i < ans.size(); ++i)
    161             printf("%d%c", ans[i], i == ans.size() - 1 ? '
    ' : ' ');
    162     }
    163     return 0;
    164 }
    View Code
  • 相关阅读:
    [NOI2016]循环之美(杜教筛)
    [CF600E]Dsu on tree
    [POI2015]Myjnie
    [POI2015]Odwiedziny
    [POI2015]Logistyka
    [POI2015]Wilcze doły
    [POI2017]Sabotaż
    [BZOJ3928/4048]Outer space invaders
    [BZOJ5109]大吉大利,晚上吃鸡!
    [AGC016E]Poor Turkeys
  • 原文地址:https://www.cnblogs.com/LJ-blog/p/4765199.html
Copyright © 2020-2023  润新知