tcbpg

Untitled

Aug 18th, 2011
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.03 KB | None | 0 0
  1. //UVa 10511 Councelling
  2.  
  3. #include <iostream>
  4. #include <cstdio>
  5. #include <vector>
  6. #include <cstring>
  7. #include <map>
  8. #include <queue>
  9. #include <algorithm>
  10. #include <sstream>
  11.  
  12. using namespace std;
  13.  
  14. #define forn(i, n) for(int i = 0; i < (int) (n); i++)
  15. #define forsn(i, s, n) for(int i = (s); i < (int) (n); i++)
  16. #define forall(i, c) for(typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
  17. #define all(v) (v).begin(), (v).end()
  18. #define isIn(i, c) ((c).find(i) != (c).end())
  19.  
  20. const int MAXN = 10100;
  21. const int INF = 20000000;
  22.  
  23. struct Eje{ long long f,m; long long d(){ return m-f;}};
  24. typedef map<int, Eje> MIE; MIE red[MAXN];
  25. int N, F, D;
  26.  
  27. void iniG(int n, int f, int d){N = n; F = f; D = d; fill(red, red+N, MIE());}
  28. void aEje(int d, int h, int m){ red[d][h].m = m; red[d][h].f = 0;}
  29.  
  30. #define DIF_F(i, j) (red[i][j].d())
  31. #define DIF_FI(i) (i->second.d())
  32. int v[MAXN];
  33. long long camAu(){
  34.     fill(v, v+N, -1);
  35.     queue<int> c;
  36.     c.push(F);
  37.     while(!(c.empty()) && v[D] == -1){
  38.         int n = c.front(); c.pop();
  39.         forall(i, red[n])
  40.             if(v[i->first] == -1 && DIF_FI(i) > 0){
  41.                 v[i->first] = n; c.push(i->first);
  42.             }
  43.     }
  44.     if(v[D] == -1) return 0;
  45.     int n = D; long long f = DIF_F(v[n], n);
  46.     while(n != F){
  47.         f = min(f, DIF_F(v[n], n)); n = v[n];
  48.     }
  49.     n = D;
  50.     while(n != F){;
  51.         red[n][v[n]].f = -(red[v[n]][n].f += f);
  52.         n = v[n];
  53.     }
  54.  
  55.     return f;
  56. }
  57.  
  58. long long flujo(){ long long tot = 0, c; do{ tot += (c = camAu());}while(c > 0); return tot; }
  59.  
  60. int main(){
  61. #ifdef ACM
  62.     freopen("test.in", "r", stdin);
  63. #endif
  64.     map<string, int> clubs, partidos;
  65.     vector<string> personas;
  66.     vector<int> p;
  67.  
  68.     vector<string> clubnames;
  69.     vector<int> miembros[MAXN];
  70.  
  71.     int nclubs, npartidos;
  72.     int t; scanf("%d\n\n", &t);
  73.  
  74.     while(t-- > 0){
  75.         nclubs = npartidos = 0;
  76.         clubs.clear(); partidos.clear(); personas.clear();
  77.         clubnames.clear(); p.clear(); miembros[0].clear();
  78.  
  79.         string s;
  80.         while(getline(cin, s) && !s.empty()){
  81.             string nombre, partido, club;
  82.  
  83.             istringstream ss(s);
  84.             ss >> nombre >> partido;
  85.             personas.push_back(nombre);
  86.  
  87.             if(!isIn(partido, partidos)){ partidos[partido] = npartidos++; }
  88.             p.push_back(partidos[partido]);
  89.  
  90.             while(ss >> club){
  91.                 if(!isIn(club, clubs)){
  92.                     miembros[nclubs].clear();
  93.                     clubs[club] = nclubs++;
  94.                     clubnames.push_back(club);
  95.                 }
  96.  
  97.                 miembros[ clubs[club] ].push_back(personas.size()-1);
  98.             }
  99.         }
  100.  
  101.         int npersonas = personas.size();
  102.         iniG(2+nclubs+npartidos+npersonas, 0, 1+nclubs+npartidos+npersonas);
  103.  
  104.         forn(i, nclubs) aEje(0, 1+i, 1);
  105.         forn(i, nclubs) forn(j, miembros[i].size()) aEje(1+i, 1+nclubs+miembros[i][j], 1);
  106.         forn(i, npersonas) aEje(1+nclubs+i, 1+nclubs+npersonas+p[i], 1);
  107.         forn(i, npartidos) aEje(1+nclubs+npersonas+i, 1+npartidos+nclubs+npersonas, (nclubs+1)/2-1);
  108.  
  109.         int res = flujo();
  110.  
  111.         if(res != nclubs) cout << "Impossible." << endl;
  112.         else{
  113.             forn(i, nclubs)
  114.                 forn(j, npersonas)
  115.                     if(red[1+i][1+nclubs+j].f == 1)
  116.                         cout << personas[j] << " " << clubnames[i] << endl;
  117.         }
  118.  
  119.         if(t > 0) cout << endl;
  120.     }
  121.  
  122.     return 0;
  123. }
Advertisement
Add Comment
Please, Sign In to add comment