选自ZJOI2007 捉迷藏
BZOJ 1095: [ZJOI2007]Hide 捉迷藏
考试的时候打了个暴力,连边之后暴力修改, spfa跑最长路, 但是一想, 这是棵树啊!两点之间路径唯一啊!dfs就好了啊(但我还是写了spfa求最短路, e[i].dis = 1) 太太太暴力了QAQ
这里我要吐槽一下数据, 交到oj上省选的数据都给我40分!队内互测只有十分QAQ
贴一下我40分代码QAQ
1 #include<queue> 2 #include<cstdio> 3 #include<cstring> 4 #include<iostream> 5 using namespace std; 6 const int maxn = 3030, maxm = 10010, inf = 99999999; 7 int n, m, num = 0, head[maxm], dis[maxn]; 8 bool init[maxn], vis[maxn];//0 关 9 char s[3]; 10 struct edge { 11 int nxt, to, dis; 12 }e[maxm<<1]; 13 int read() { 14 char ch = getchar(); int x = 0, f = 1; 15 while(ch<'0'||ch>'9') {if(ch=='0') f = -1; ch = getchar();} 16 while(ch>='0'&&ch<='9') {x = x * 10 + ch - '0'; ch = getchar();} 17 return x * f; 18 } 19 void add(int from, int to) { 20 e[++num].nxt = head[from]; 21 e[num].to = to; 22 e[num].dis = 1; 23 head[from] = num; 24 } 25 void spfa(int sta) { 26 queue<int>q; 27 for(int i = 1; i <= n; i++) { 28 vis[i] = 0; 29 dis[i] = inf; 30 } 31 vis[sta] = 1, dis[sta] = 0, q.push(sta); 32 while(!q.empty()) { 33 int u = q.front(); 34 q.pop(); 35 vis[u] = 0; 36 for(int i = head[u]; i; i = e[i].nxt) { 37 int v = e[i].to; 38 if(dis[v] > dis[u] + e[i].dis) { 39 dis[v] = dis[u] + e[i].dis; 40 if(!vis[v]) { 41 vis[v] = 1; 42 q.push(v); 43 } 44 } 45 } 46 } 47 } 48 void work() { 49 int flag = 0, ans = 0; 50 for(int i = 1; i <= n; i++) { 51 if(!init[i]) { 52 flag++; 53 spfa(i); 54 for(int j = 1; j <= n; j++) { 55 if(!init[j]) ans = max(dis[j], ans); 56 } 57 } 58 } 59 if(flag == 1 || flag == 0) printf("%d ", flag - 1); 60 else printf("%d ", ans); 61 } 62 int main() { 63 // freopen("practice.in", "r", stdin); 64 // freopen("practice.out", "w", stdout); 65 scanf("%d", &n); 66 for(int i = 1; i < n; i++) { 67 int x = read(), y = read(); 68 add(x, y), add(y, x); 69 } 70 scanf("%d", &m); 71 for(int i = 1; i <= m; i++) { 72 scanf("%s", s); 73 if(s[0] == 'G') work(); 74 else if(s[0] == 'C') { 75 int x = read(); 76 (!init[x]) ? (init[x] = 1) : (init[x] = 0); 77 } 78 } 79 return 0; 80 }
正解(括号序列+线段树维护)我还在学习过程中QAQ争取今晚搞完QAQAQ