【模拟赛】捉迷藏

选自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\n", flag - 1);
60     else printf("%d\n", 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

猜你喜欢

转载自www.cnblogs.com/Hwjia/p/9852333.html
今日推荐