【HDOJ】1669 Jamie's Contact Groups

二分+二分图多重匹配。

  1 /* 1669 */
  2 #include <iostream>
  3 #include <string>
  4 #include <map>
  5 #include <queue>
  6 #include <set>
  7 #include <stack>
  8 #include <vector>
  9 #include <deque>
 10 #include <algorithm>
 11 #include <cstdio>
 12 #include <cmath>
 13 #include <ctime>
 14 #include <cstring>
 15 #include <climits>
 16 #include <cctype>
 17 #include <cassert>
 18 #include <functional>
 19 #include <iterator>
 20 #include <iomanip>
 21 using namespace std;
 22 //#pragma comment(linker,"/STACK:102400000,1024000")
 23 
 24 #define sti                set<int>
 25 #define stpii            set<pair<int, int> >
 26 #define mpii            map<int,int>
 27 #define vi                vector<int>
 28 #define pii                pair<int,int>
 29 #define vpii            vector<pair<int,int> >
 30 #define rep(i, a, n)     for (int i=a;i<n;++i)
 31 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 32 #define clr                clear
 33 #define pb                 push_back
 34 #define mp                 make_pair
 35 #define fir                first
 36 #define sec                second
 37 #define all(x)             (x).begin(),(x).end()
 38 #define SZ(x)             ((int)(x).size())
 39 #define lson            l, mid, rt<<1
 40 #define rson            mid+1, r, rt<<1|1
 41 
 42 const int maxn = 1005;
 43 const int maxm = 505;
 44 bool M[maxn][maxm];
 45 bool visit[maxm];
 46 int can[maxm][maxm];
 47 int sz[maxm];
 48 int n, gn, bound;
 49 
 50 bool dfs(int u) {
 51     rep(i, 0, gn) {
 52         if (M[u][i] && !visit[i]) {
 53             visit[i] = true;
 54             if (sz[i] < bound) {
 55                 can[i][sz[i]++] = u;
 56                 return true;
 57             }
 58             rep(j, 0, sz[i]) {
 59                 if (dfs(can[i][j])) {
 60                     can[i][j] = u;
 61                     return true;
 62                 }
 63             }
 64         }
 65     }
 66     
 67     return false;
 68 }
 69 
 70 bool judge(int bound_) {
 71     bound = bound_;
 72     memset(sz, 0, sizeof(sz));
 73     rep(i, 0, n) {
 74         memset(visit, false, sizeof(visit));
 75         if (!dfs(i))
 76             return false;
 77     }
 78     
 79     return true;
 80 }
 81 
 82 void solve() {
 83     int l, r, mid;
 84     int ans;
 85     
 86     l = 0;
 87     ans = r = n;
 88     while (l <= r) {
 89         mid = (l + r) >> 1;
 90         if (judge(mid)) {
 91             ans = mid;
 92             r = mid - 1;
 93         } else {
 94             l = mid + 1;
 95         }
 96     }
 97     
 98     printf("%d\n", ans);
 99 }
100 
101 int main() {
102     ios::sync_with_stdio(false);
103     #ifndef ONLINE_JUDGE
104         freopen("data.in", "r", stdin);
105         freopen("data.out", "w", stdout);
106     #endif
107     
108     char name[20];
109     int gid;
110     char ch;
111     
112     while (scanf("%d %d", &n, &gn)!=EOF && (n||gn)) {
113         memset(M, false, sizeof(M));
114         rep(i, 0, n) {
115             scanf("%s", name);
116             while (1) {
117                 scanf("%d%c", &gid, &ch);
118                 M[i][gid] = true;
119                 if (ch == '\n')
120                     break;
121             }
122         }
123         solve();
124     }
125     
126     #ifndef ONLINE_JUDGE
127         printf("time = %d.\n", (int)clock());
128     #endif
129     
130     return 0;
131 }

 二分+网络流Dinic也可以解。

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

 

posted on 2015-11-24 10:48  Bombe  阅读(146)  评论(0编辑  收藏  举报

导航