【HDOJ】2242 考研路茫茫——空调教室

tarjan缩点,然后树形dp一下可解。重点是重边的处理。

  1 /* 2242 */
  2 #include <iostream>
  3 #include <sstream>
  4 #include <string>
  5 #include <map>
  6 #include <queue>
  7 #include <set>
  8 #include <stack>
  9 #include <vector>
 10 #include <deque>
 11 #include <bitset>
 12 #include <algorithm>
 13 #include <cstdio>
 14 #include <cmath>
 15 #include <ctime>
 16 #include <cstring>
 17 #include <climits>
 18 #include <cctype>
 19 #include <cassert>
 20 #include <functional>
 21 #include <iterator>
 22 #include <iomanip>
 23 using namespace std;
 24 //#pragma comment(linker,"/STACK:102400000,1024000")
 25 
 26 #define sti                set<int>
 27 #define stpii            set<pair<int, int> >
 28 #define mpii            map<int,int>
 29 #define vi                vector<int>
 30 #define pii                pair<int,int>
 31 #define vpii            vector<pair<int,int> >
 32 #define rep(i, a, n)     for (int i=a;i<n;++i)
 33 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 34 #define clr                clear
 35 #define pb                 push_back
 36 #define mp                 make_pair
 37 #define fir                first
 38 #define sec                second
 39 #define all(x)             (x).begin(),(x).end()
 40 #define SZ(x)             ((int)(x).size())
 41 #define lson            l, mid, rt<<1
 42 #define rson            mid+1, r, rt<<1|1
 43 
 44 typedef struct {
 45     int v, nxt;
 46 } edge_t;
 47 
 48 const int maxv = 10005;
 49 const int maxe = 40005;
 50 int head[maxv], l;
 51 edge_t E[maxe];
 52 int low[maxv], pre[maxv], bn[maxv];
 53 int S[maxv], top;
 54 int block, dfs_clock;
 55 int num[maxv], tot[maxv], sum;
 56 int head_[maxv], l_;
 57 edge_t E_[maxe];
 58 bool visit[maxv];
 59 int n, m;
 60 int ans;
 61 
 62 void init() {
 63     l = block = dfs_clock = 0;
 64     top = 0;
 65     memset(pre, 0, sizeof(pre));
 66     memset(bn, 0, sizeof(bn));
 67     memset(head, -1, sizeof(head));
 68 }
 69 
 70 void init_() {
 71     l_ = sum = 0;
 72     memset(tot, 0, sizeof(tot));
 73     memset(head_, -1, sizeof(head_));
 74     memset(visit, false, sizeof(visit));
 75     ans = INT_MAX;
 76 }
 77 
 78 void addEdge(int u, int v) {
 79     E[l].v = v;
 80     E[l].nxt = head[u];
 81     head[u] = l++;
 82 
 83     E[l].v = u;
 84     E[l].nxt = head[v];
 85     head[v] = l++;
 86 }
 87 
 88 void addEdge_(int u, int v) {
 89     E_[l_].v = v;
 90     E_[l_].nxt = head_[u];
 91     head_[u] = l_++;
 92 
 93     E_[l_].v = u;
 94     E_[l_].nxt = head_[v];
 95     head_[v] = l_++;
 96 }
 97 
 98 void tarjan(int u, int fa) {
 99     int v, k;
100     bool flag = true;
101     
102     S[top++] = u;
103     pre[u] = low[u] = ++dfs_clock;
104     for (k=head[u]; k!=-1; k=E[k].nxt) {
105         v = E[k].v;
106         if (v == fa && flag) {
107             flag = false;
108             continue;
109         }
110 
111         if (!pre[v]) {
112             tarjan(v, u);
113             low[u] = min(low[u], low[v]);
114         } else if (!bn[v]) {
115             low[u] = min(low[u], pre[v]);
116         }
117     }
118 
119     if (low[u] == pre[u]) {
120         ++block;
121         do {
122             bn[S[--top]] = block;
123         } while (S[top]!=u);
124     }
125 }
126 
127 void dfs(int u, int fa) {
128     int v, k;
129 
130     visit[u] = true;
131     for (k=head_[u]; k!=-1; k=E_[k].nxt) {
132         v = E_[k].v;
133         if (v==fa || visit[v])
134             continue;
135         dfs(v, u);
136         tot[u] += tot[v];
137     }
138 
139     ans = min(ans, abs(sum-tot[u]-tot[u]));
140 }
141 
142 void solve() {
143     rep(i, 0, n) {
144         if (!pre[i])
145             tarjan(i, -1);
146     }
147 
148     #ifndef ONLINE_JUDGE
149         printf("block = %d\n", block);
150     #endif
151     
152     if (block <= 1) {
153         puts("impossible");
154         return ;
155     }
156 
157     init_();
158     int u, v, k;
159 
160     for (u=0; u<n; ++u) {
161         tot[bn[u]] += num[u];
162         sum += num[u];
163         for (k=head[u]; k!=-1; k=E[k].nxt) {
164             v = E[k].v;
165             if (bn[v] != bn[u]) {
166                 addEdge_(bn[u], bn[v]);
167             }
168         }
169     }
170 
171     dfs(1, -1);
172     printf("%d\n", ans);
173 }
174 
175 int main() {
176     ios::sync_with_stdio(false);
177     #ifndef ONLINE_JUDGE
178         freopen("data.in", "r", stdin);
179         freopen("data.out", "w", stdout);
180     #endif
181 
182     int u, v;
183 
184     while (scanf("%d %d", &n, &m)!=EOF) {
185         rep(i, 0, n)
186             scanf("%d", &num[i]);
187         init();
188         rep(i, 0, m) {
189             scanf("%d %d", &u, &v);
190             addEdge(u, v);
191         }
192         solve();
193     }
194 
195     #ifndef ONLINE_JUDGE
196         printf("time = %d.\n", (int)clock());
197     #endif
198 
199     return 0;
200 }

数据生成器。

 1 import sys
 2 import string
 3 from random import randint
 4 
 5     
 6 def GenData(fileName):
 7     with open(fileName, "w") as fout:
 8         t = 10
 9         for tt in xrange(t):
10             n = randint(100, 200)
11             m = randint(n/10, n+n/10)
12             fout.write("%d %d\n" % (n, m))
13             dataList = []
14             for i in xrange(n):
15                 x = randint(0, 1000)
16                 dataList.append(x)
17             fout.write(" ".join(map(str, dataList)) + "\n")
18             for i in xrange(m):
19                 a = randint(0, n)
20                 b = randint(0, n)
21                 fout.write("%d %d\n" % (a, b))
22                 
23         
24 def MovData(srcFileName, desFileName):
25     with open(srcFileName, "r") as fin:
26         lines = fin.readlines()
27     with open(desFileName, "w") as fout:
28         fout.write("".join(lines))
29 
30         
31 def CompData():
32     print "comp"
33     srcFileName = "F:\Qt_prj\hdoj\data.out"
34     desFileName = "F:\workspace\cpp_hdoj\data.out"
35     srcLines = []
36     desLines = []
37     with open(srcFileName, "r") as fin:
38         srcLines = fin.readlines()
39     with open(desFileName, "r") as fin:
40         desLines = fin.readlines()
41     n = min(len(srcLines), len(desLines))-1
42     for i in xrange(n):
43         ans2 = int(desLines[i])
44         ans1 = int(srcLines[i])
45         if ans1 > ans2:
46             print "%d: wrong" % i
47 
48             
49 if __name__ == "__main__":
50     srcFileName = "F:\Qt_prj\hdoj\data.in"
51     desFileName = "F:\workspace\cpp_hdoj\data.in"
52     GenData(srcFileName)
53     MovData(srcFileName, desFileName)
54     
55     

 

你可能感兴趣的:(【HDOJ】2242 考研路茫茫——空调教室)