双连通
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\n", (tot+1)/2); 102 } 103 return 0; 104 }
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\n", 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\n", ans); 109 } 110 return 0; 111 }
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\n", 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\n", ans); 134 } 135 }
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\n", ans1, ans2); 121 } 122 return 0; 123 }
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\n", 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\n", ++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\n", i, num[i]); 118 ok = 1; 119 } 120 } 121 if(!ok) puts(" No SPF nodes"); 122 puts(""); 123 } 124 }
给一个无向图。若删除某些路径,则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\n", 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 ? '\n' : ' '); 162 } 163 return 0; 164 }