Chapter I 强连通分量以及割点
T1 poj 3180 The Cow Prom
Time cost: 35min
比较明显的板子题
缩点记录一下分量点数
注意除去点数少于2的情况
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #define rep(i,a,n) for(int i = a;i <= n;i++) 6 #define per(i,n,a) for(int i = n;i >= a;i--) 7 using namespace std; 8 typedef long long ll; 9 ll read() { 10 ll as = 0,fu = 1; 11 char c = getchar(); 12 while(c < '0' || c > '9') { 13 if(c == '-') fu = -1; 14 c = getchar(); 15 } 16 while(c >= '0' && c <= '9') { 17 as = as * 10 + c - '0'; 18 c = getchar(); 19 } 20 return as * fu; 21 } 22 const int N = 50005; 23 //head 24 int n,m,ans; 25 int mo[N],nxt[N],head[N],cnt; 26 void add(int x,int y) { 27 mo[++cnt] = y; 28 nxt[cnt] = head[x]; 29 head[x] = cnt; 30 } 31 32 int dfn[N],low[N],stk[N],sze[N],col[N]; 33 int top,idx,scc; 34 bool ins[N]; 35 void tarjan(int x) { 36 dfn[x] = low[x] = ++idx; 37 stk[++top] = x,ins[x] = 1; 38 for(int i = head[x];i;i = nxt[i]) { 39 int sn = mo[i]; 40 if(!dfn[sn]) { 41 tarjan(sn); 42 low[x] = min(low[x],low[sn]); 43 } else if(ins[sn]) low[x] = min(low[x],dfn[sn]); 44 } 45 if(low[x] == dfn[x]) { 46 int t = -1; 47 scc++; 48 while(t != x) { 49 t = stk[top--]; 50 ins[t] = 0; 51 col[t] = scc; 52 sze[scc]++; 53 } 54 } 55 } 56 57 58 int main() { 59 n = read(); 60 m = read(); 61 rep(i,1,m) { 62 int x = read(); 63 int y = read(); 64 add(x,y); 65 } 66 rep(i,1,n) if(!dfn[i]) tarjan(i); 67 rep(i,1,scc) if(sze[i] >= 2) ans++; 68 printf("%d ",ans); 69 return 0; 70 }
T2 poj 1236 Network of Schools
Time cost: 45min
不再是板子
题意较为明显的拓扑意识 先缩点
对于剩下的DAG
第一问 只要所有入度为0的点放入软件就行
第二问 考虑最坏情况 选择了一个出度为0的点放软件
所以就能要保证入度为0的点都接到或者保证出度为0的点都能发出去
所以答案就是rdu[]==0和cdu[]==0的较大值
Code:(这里是luogu加强版P2812)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #define ms(a,b) memset(a,b,sizeof a) 6 #define rep(i,a,n) for(int i = a;i <= n;i++) 7 #define per(i,n,a) for(int i = n;i >= a;i--) 8 using namespace std; 9 typedef long long ll; 10 ll read() { 11 ll as = 0,fu = 1; 12 char c = getchar(); 13 while(c < '0' || c > '9') { 14 if(c == '-') fu = -1; 15 c = getchar(); 16 } 17 while(c >= '0' && c <= '9') { 18 as = as * 10 + c - '0'; 19 c = getchar(); 20 } 21 return as * fu; 22 } 23 const int N = 10005; 24 //head 25 int n,m,ans1,ans2; 26 int mo[5000005],nxt[5000005],head[N],cnt; 27 void add(int x,int y) { 28 mo[++cnt] = y; 29 nxt[cnt] = head[x]; 30 head[x] = cnt; 31 } 32 void clr(){ms(head,0),cnt = 0;} 33 34 int dfn[N],low[N],stk[N],sze[N],col[N]; 35 int top,idx,scc; 36 bool ins[N]; 37 void tarjan(int x) { 38 dfn[x] = low[x] = ++idx; 39 stk[++top] = x,ins[x] = 1; 40 for(int i = head[x];i;i = nxt[i]) { 41 int sn = mo[i]; 42 if(!dfn[sn]) { 43 tarjan(sn); 44 low[x] = min(low[x],low[sn]); 45 } else if(ins[sn]) 46 low[x] = min(low[x],dfn[sn]); 47 } 48 if(low[x] == dfn[x]) { 49 int t = -1; 50 scc++; 51 while(t != x) { 52 t = stk[top--]; 53 ins[t] = 0; 54 col[t] = scc; 55 sze[scc]++; 56 } 57 } 58 } 59 int str[5000005],stp[5000005]; 60 int rdu[N],cdu[N]; 61 62 int main() { 63 n = read(); 64 rep(x,1,n) while(1) { 65 int y = read(); 66 if(!y) break; 67 str[++m] = x,stp[m] = y; 68 add(x,y); 69 } 70 rep(i,1,n) if(!dfn[i]) tarjan(i); 71 if(scc == 1) { 72 printf("1 0 "); 73 return 0; 74 } 75 clr(); 76 rep(i,1,m) { 77 if(col[str[i]] == col[stp[i]]) continue; 78 add(col[str[i]],col[stp[i]]); 79 cdu[col[str[i]]]++,rdu[col[stp[i]]]++; 80 } 81 rep(i,1,scc) { 82 if(!rdu[i]) ans1++; 83 if(!cdu[i]) ans2++; 84 } 85 printf("%d %d ",ans1,max(ans1,ans2)); 86 }
Chapter II 图的割点、桥与双连通分量
T1 poj3177 Redundant Paths
Time cost:55min
例题还是说一下(边双做的比较少……)
求加最少的边使得整个图为一边双
先找出所有的桥/边双 然后缩点
发现变成一个点数为边双个数的树
考虑树上的一条链 加一条边就是一个边双
所以最后加边的个数就是(叶节点个数+1)/2
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #define ms(a,b) memset(a,b,sizeof a) 6 #define rep(i,a,n) for(int i = a;i <= n;i++) 7 #define per(i,n,a) for(int i = n;i >= a;i--) 8 using namespace std; 9 typedef long long ll; 10 ll read() { 11 ll as = 0,fu = 1; 12 char c = getchar(); 13 while(c < '0' || c > '9') { 14 if(c == '-') fu = -1; 15 c = getchar(); 16 } 17 while(c >= '0' && c <= '9') { 18 as = as * 10 + c - '0'; 19 c = getchar(); 20 } 21 return as * fu; 22 } 23 const int N = 20005; 24 //head 25 int n,m,ans; 26 int head[N],nxt[N],fo[N],mo[N],cnt = 1; 27 bool cut[N]; 28 void _add(int x,int y) { 29 fo[++cnt] = x; 30 mo[cnt] = y; 31 nxt[cnt] = head[x]; 32 head[x] = cnt; 33 } 34 void add(int x,int y){if(x^y)_add(x,y),_add(y,x);} 35 36 int dfn[N],low[N],stk[N],col[N]; 37 int top,idx,scc; 38 bool ins[N]; 39 void tarjan(int x,int f) { 40 dfn[x] = low[x] = ++idx; 41 stk[++top] = x,ins[x] = 1; 42 bool flag = 0; 43 for(int i = head[x];i;i = nxt[i]) { 44 int sn = mo[i]; 45 if(sn == f && !flag) { 46 flag = 1; 47 continue; 48 } 49 if(!dfn[sn]) { 50 tarjan(sn,x); 51 low[x] = min(low[x],low[sn]); 52 } else if(ins[sn]) low[x] = min(low[x],dfn[sn]); 53 } 54 if(low[x] == dfn[x]) { 55 int t = -1; 56 scc++; 57 while(t!=x) { 58 t = stk[top--]; 59 col[t] = scc; 60 ins[t] = 0; 61 } 62 } 63 } 64 int du[N]; 65 int main() { 66 n = read(); 67 m = read(); 68 rep(i,1,m) { 69 int x = read(); 70 int y = read(); 71 add(x,y); 72 } 73 rep(i,1,n) if(!dfn[i]) tarjan(i,i); 74 rep(x,1,n) { 75 for(int i = head[x];i;i = nxt[i]) { 76 int sn = mo[i]; 77 if(col[x] ^ col[sn]) du[col[x]]++,du[col[sn]]++; 78 } 79 } 80 rep(i,1,scc) if(du[i] == 2) ans++; 81 printf("%d ",ans+1 >> 1); 82 return 0; 83 }
T2 poj 1523 SPF
Time cost: 60min
不敢说是板……因为输入输出贼恶心
每个方案之间还要换行……
然后WA了一次是因为考虑根节点为割点的时候多算了1
整体的思路就是求出割点弹栈的时候记录一下这个点“做了几次割点”
实现的时候就是cut[x] =1变成cut[x]++就Ok
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #define ms(a,b) memset(a,b,sizeof a) 6 #define rep(i,a,n) for(int i = a;i <= n;i++) 7 #define per(i,n,a) for(int i = n;i >= a;i--) 8 using namespace std; 9 typedef long long ll; 10 ll read() { 11 ll as = 0,fu = 1; 12 char c = getchar(); 13 while(c < '0' || c > '9') { 14 if(c == '-') fu = -1; 15 c = getchar(); 16 } 17 while(c >= '0' && c <= '9') { 18 as = as * 10 + c - '0'; 19 c = getchar(); 20 } 21 return as * fu; 22 } 23 const int N = 20005; 24 //head 25 int minn,maxx; 26 int head[N],mo[N],nxt[N],cnt; 27 void _add(int x,int y) { 28 mo[++cnt] = y; 29 nxt[cnt] = head[x]; 30 head[x] = cnt; 31 } 32 void add(int x,int y) {if(x^y)_add(x,y),_add(y,x);} 33 34 int dfn[N],low[N],col[N],sze[N],stk[N]; 35 int top,scc,idx; 36 int cut[N]; 37 void tarjan(int x,bool rt) { 38 dfn[x] = low[x] = ++idx; 39 stk[++top] = x; 40 for(int i = head[x];i;i = nxt[i]) { 41 int sn = mo[i]; 42 if(!dfn[sn]) { 43 tarjan(sn,0); 44 low[x] = min(low[x],low[sn]); 45 if(low[sn] == dfn[x]) { 46 int t = -1; 47 sze[++scc]++; 48 while(t != sn) { 49 t = stk[top--]; 50 sze[scc]++; 51 col[t] = scc; 52 } 53 cut[x]++; 54 } 55 } else low[x] = min(low[x],dfn[sn]); 56 } 57 if(rt) cut[x]--; 58 } 59 60 void solve() { 61 tarjan(minn,1); 62 bool flag = 0; 63 rep(i,minn,maxx) if(cut[i]) { 64 flag = 1; 65 printf(" SPF node %d leaves %d subnets ",i,cut[i] + 1); 66 } 67 if(!flag) puts(" No SPF nodes"); 68 } 69 70 void clr() { 71 ms(head,0); 72 ms(dfn,0),ms(low,0),ms(cut,0); 73 top = cnt = idx = scc = 0; 74 } 75 76 int main() { 77 int T = 0; 78 while(1) { 79 int x,y; 80 clr(); 81 x = read(); 82 if(!x) break; 83 y = read(); 84 add(x,y); 85 minn = min(x,y); 86 maxx = max(x,y); 87 while(1) { 88 x = read(); 89 if(!x) break; 90 y = read(); 91 add(x,y); 92 minn = min(min(x,y),minn); 93 maxx = max(max(x,y),maxx); 94 } 95 printf("Network #%d ",++T); 96 solve(); 97 puts(""); 98 } 99 return 0; 100 }
T3 poj 2942 Knights of the Round Table
Time cost : 85min
Tarjan快结束了就出一个建图及其恶心的题……
给你的憎恨关系要先转成友好关系(想到这过去了30min)
然后求奇数大小点双的个数 => 二分图染色!
发现下一个点已经有相同的颜色了就返回true
注意:
1.相反颜色继续向后找其他边而不是return 0
2.割点在每个点双里面都要重新染色 (然后就需要vector存点...)
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #include<queue> 6 #define ms(a,b) memset(a,b,sizeof a) 7 #define rep(i,a,n) for(int i = a;i <= n;i++) 8 #define per(i,n,a) for(int i = n;i >= a;i--) 9 #define inf 2147483647 10 using namespace std; 11 typedef long long ll; 12 ll read() { 13 ll as = 0,fu = 1; 14 char c = getchar(); 15 while(c < '0' || c > '9') { 16 if(c == '-') fu = -1; 17 c = getchar(); 18 } 19 while(c >= '0' && c <= '9') { 20 as = as * 10 + c - '0'; 21 c = getchar(); 22 } 23 return as * fu; 24 } 25 const int N = 1005; 26 //head 27 int n,m; 28 int v[N][N]; 29 30 int dfn[N],low[N],stk[N],col[N]; 31 int scc,idx,top; 32 vector<int> mem[N]; 33 void tarjan(int x,int f) { 34 dfn[x] = low[x] = ++idx; 35 stk[++top] = x; 36 rep(y,1,n) { 37 if(!v[x][y] || x == y) continue; 38 if(!dfn[y]) { 39 tarjan(y,x); 40 low[x] = min(low[x],low[y]); 41 if(low[y] == dfn[x]) { 42 int t = -1; 43 mem[++scc].push_back(x); 44 while(t != y) { 45 t = stk[top--]; 46 mem[scc].push_back(t); 47 } 48 } 49 } else low[x] = min(low[x],dfn[y]); 50 } 51 } 52 53 int mrk[N]; 54 bool paint(int x,bool d) { 55 mrk[x] = d; 56 rep(y,1,n) { 57 if(!v[x][y] || x == y) continue; 58 if(col[x] ^ col[y]) continue; 59 if(mrk[y] == mrk[x]) return 1; 60 else if(mrk[y] == -1 && paint(y,d^1)) return 1; 61 } 62 return 0; 63 } 64 int ans[N]; 65 void clr() { 66 rep(i,0,n+1) rep(j,0,n+1) v[i][j] = true; 67 rep(i,1,scc) mem[i].clear(); 68 idx = scc = top = 0; 69 ms(dfn,0),ms(low,0),ms(col,0),ms(ans,0); 70 } 71 72 int main() { 73 while(1) { 74 n = read(),m = read(); 75 if(!n && !m) return 0; 76 clr(); 77 rep(i,1,m) { 78 int x = read(),y = read(); 79 v[y][x] = v[x][y] = 0; 80 } 81 rep(i,1,n) if(!dfn[i]) tarjan(i,i); 82 rep(i,1,scc) { 83 ms(mrk,-1); 84 int sze = (int)mem[i].size(); 85 rep(j,0,sze-1) col[mem[i][j]] = i; 86 if(paint(mem[i][0],0)) { 87 rep(j,0,sze - 1) ans[mem[i][j]] = 1; 88 } 89 } 90 int res = 0; 91 rep(i,1,n) res += !ans[i]; 92 printf("%d ",res); 93 } 94 }
Chapter III 2-SAT
T1 poj 3678 Katu Puzzle
Time cost: 45min
2-SAT中能遇到的比较常见的限制都在这道题里了
分析一下
1.xΛy == 1 x,y都不为0 连边x->x+n , y->y+n
2.xΛy == 0 <=> ~xV~y == 1 <=> 连边x->y+n , y->x+n
3.xVy == 1 连边x+n->y , y+n -> x
4.xVy == 0 x,y都为0 连边
这里注意一下 就是异或是能由一个直接确定另一个的 所以需要加四条边
当然也可以考虑成满足或 不满足与(就不写了 代码里有)
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #define itn int 6 #define ms(a,b) memset(a,b,sizeof a) 7 #define rep(i,a,n) for(int i = a;i <= n;i++) 8 #define per(i,n,a) for(int i = n;i >= a;i--) 9 using namespace std; 10 typedef long long ll; 11 ll read() { 12 ll as = 0,fu = 1; 13 char c = getchar(); 14 while(c < '0' || c > '9') { 15 if(c == '-') fu = -1; 16 c = getchar(); 17 } 18 while(c >= '0' && c <= '9') { 19 as = as * 10 + c - '0'; 20 c = getchar(); 21 } 22 return as * fu; 23 } 24 const int N = 3005; 25 //head 26 int n,m; 27 int head[N],nxt[N*N],mo[N*N],cnt; 28 void add(itn x,int y) { 29 mo[++cnt] = y; 30 nxt[cnt] = head[x]; 31 head[x] = cnt; 32 } 33 34 int dfn[N],low[N],stk[N],col[N]; 35 int top,scc,idx; 36 bool ins[N]; 37 void tarjan(itn x) { 38 dfn[x] = low[x] = ++idx; 39 stk[++top] = x,ins[x] = 1; 40 for(int i = head[x];i;i = nxt[i]) { 41 int sn = mo[i]; 42 if(!dfn[sn]) { 43 tarjan(sn); 44 low[x] = min(low[x],low[sn]); 45 } else if(ins[sn]) low[x] = min(low[x],dfn[sn]); 46 } 47 if(low[x] == dfn[x]) { 48 int t = -1; 49 scc++; 50 while(t!=x) { 51 t = stk[top--]; 52 ins[t] = 0; 53 col[t] = scc; 54 } 55 } 56 } 57 char s[7]; 58 int main() { 59 n = read(); 60 m = read(); 61 rep(i,1,m) { 62 int x = read() + 1; 63 int y = read() + 1; 64 bool op = read(); 65 scanf("%s",s); 66 if(s[0] == 'A') { 67 if(op) add(x+n,x),add(y+n,y); 68 else add(x,y+n),add(y,x+n); 69 } else if(s[0] == 'O') { 70 if(op) add(x+n,y),add(y+n,x); 71 else add(x,x+n),add(y,y+n); 72 } else if(s[0] == 'X'){ 73 if(op) add(x+n,y),add(y+n,x),add(x,y+n),add(y,x+n); 74 else add(x,y),add(y,x),add(x+n,y+n),add(y+n,x+n); 75 } 76 } 77 rep(i,1,n<<1) if(!dfn[i]) tarjan(i); 78 bool flag = 1; 79 rep(i,1,n) if(col[i] == col[n+i]) flag = 0; 80 flag ? puts("YES") : puts("NO"); 81 return 0; 82 }
T2 luogu P4171 [JSOI2010]满汉全席
Time cost:45min
2-SAT基础 每一对关系都是|| 逆向连边即可
(luogu读入依然坑人……)
Code:
1 // luogu-judger-enable-o2 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 #define ms(a,b) memset(a,b,sizeof a) 8 #define rep(i,a,n) for(int i = a;i <= n;i++) 9 #define per(i,n,a) for(int i = n;i >= a;i--) 10 #define inf 2147483647 11 using namespace std; 12 typedef long long ll; 13 ll read() { 14 ll as = 0,fu = 1; 15 char c = getchar(); 16 while(c < '0' || c > '9') { 17 if(c == '-') fu = -1; 18 c = getchar(); 19 } 20 while(c >= '0' && c <= '9') { 21 as = as * 10 + c - '0'; 22 c = getchar(); 23 } 24 return as * fu; 25 } 26 const int N = 4005; 27 //head 28 int n,m; 29 int head[N],nxt[N],mo[N],cnt; 30 void add(int x,int y) { 31 mo[++cnt] = y; 32 nxt[cnt] = head[x]; 33 head[x] = cnt; 34 } 35 36 int dfn[N],low[N],stk[N],col[N]; 37 int scc,idx,top; 38 bool ins[N]; 39 void tarjan(int x) { 40 dfn[x] = low[x] = ++idx; 41 stk[++top] = x,ins[x] = 1; 42 for(int i = head[x];i;i = nxt[i]) { 43 int sn = mo[i]; 44 if(!dfn[sn]) { 45 tarjan(sn); 46 low[x] = min(low[x],low[sn]); 47 } else if(ins[sn]) 48 low[x] = min(low[x],dfn[sn]); 49 } 50 if(dfn[x] == low[x]) { 51 int t = -1; 52 scc++; 53 while(t != x) { 54 t = stk[top--]; 55 col[t] = scc; 56 ins[t] = 0; 57 } 58 } 59 } 60 61 int rev(int x){return x>n?x-n:x+n;} 62 void clr() { 63 n = m = 0; 64 ms(head,0),ms(dfn,0),ms(low,0),ms(col,0); 65 scc = cnt = idx = 0; 66 } 67 68 void solve() { 69 clr(); 70 n = read(); 71 m = read(); 72 rep(i,1,m) { 73 int x,y; 74 rep(t,0,1) { 75 int num = 0; 76 char s[10]; 77 scanf("%s",s); 78 int l = strlen(s); 79 rep(j,1,l-1) num = num * 10 + s[j] - '0'; 80 if(s[0] == 'h') num += n; 81 t ? y = num : x = num; 82 } 83 add(rev(x),y),add(rev(y),x); 84 } 85 rep(i,1,n<<1) if(!dfn[i]) tarjan(i); 86 bool flag = 1; 87 rep(i,1,n) if(col[i] == col[n+i]) { 88 flag = 0; 89 break; 90 } 91 flag ? puts("GOOD") : puts("BAD"); 92 } 93 94 int main() { 95 int T = read(); 96 while(T--) solve(); 97 return 0; 98 }
T3 poj3177 Wedding
Time cost:100min
最后输出出锅调一个点……
题意就是比较明显的2-SAT
但是这个题已经拆好点了
我们把新郎一边为0新郎一边为1 那么每对关系就是||
最后要新郎到新娘连一条边表示求的是与新郎坐在一起的人
大力建图就OK
最后输出的时候注意空格的问题……
还有读入的时候忘了数字可以有多位就一直RE……
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #define itn int 6 #define ms(a,b) memset(a,b,sizeof a) 7 #define rep(i,a,n) for(int i = a;i <= n;i++) 8 #define per(i,n,a) for(int i = n;i >= a;i--) 9 using namespace std; 10 typedef long long ll; 11 ll read() { 12 ll as = 0,fu = 1; 13 char c = getchar(); 14 while(c < '0' || c > '9') { 15 if(c == '-') fu = -1; 16 c = getchar(); 17 } 18 while(c >= '0' && c <= '9') { 19 as = as * 10 + c - '0'; 20 c = getchar(); 21 } 22 return as * fu; 23 } 24 const int N = 2005; 25 //head 26 int n,m; 27 int head[N],nxt[400005],mo[400005],cnt; 28 void add(int x,int y) { 29 mo[++cnt] = y; 30 nxt[cnt] = head[x]; 31 head[x] = cnt; 32 } 33 int dfn[N],low[N],stk[N],col[N]; 34 int top,idx,scc; 35 bool ins[N]; 36 void tarjan(int x) { 37 dfn[x] = low[x] = ++idx; 38 stk[++top] = x,ins[x] = 1; 39 for(int i = head[x];i;i = nxt[i]) { 40 int sn = mo[i]; 41 if(!dfn[sn]) { 42 tarjan(sn); 43 low[x] = min(low[x],low[sn]); 44 } else if(ins[sn]) 45 low[x] = min(low[x],dfn[sn]); 46 } 47 if(low[x] == dfn[x]) { 48 int t = -1; 49 ++scc; 50 while(t != x) { 51 t = stk[top--]; 52 ins[t] = 0; 53 col[t] = scc; 54 } 55 } 56 } 57 int rev(int x){return x>n?x-n:x+n;} 58 void clr() { 59 ms(head,0),ms(dfn,0),ms(low,0),ms(col,0); 60 idx = scc = cnt = 0; 61 } 62 63 int main() { 64 while(1) { 65 n = read(); 66 m = read(); 67 if(!n && !m) return 0; 68 clr(); 69 rep(i,1,m) { 70 int x,y; 71 char c1,c2; 72 scanf("%d%c %d%c",&x,&c1,&y,&c2); 73 x = x + 1 + (c1 == 'h') * n; 74 y = y + 1 + (c2 == 'h') * n; 75 add(x,rev(y)),add(y,rev(x)); 76 } 77 add(1,n+1); 78 rep(i,1,n<<1) if(!dfn[i]) tarjan(i); 79 bool flag = 1; 80 rep(i,1,n) if(col[i] == col[n+i]) flag = 0; 81 if(!flag) { 82 puts("bad luck"); 83 continue; 84 } 85 rep(i,2,n) 86 printf("%d%c ",i-1,col[i] > col[i+n] ? 'w' : 'h'); 87 puts(""); 88 } 89 }
Chapter IV Euleriar path
没找到什么经典题啊…… 就整一下概念吧