Advertisement
Guest User

Untitled

a guest
Mar 30th, 2015
236
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.59 KB | None | 0 0
  1. #include <cstdio>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <queue>
  5. #include <unordered_set>
  6. using namespace std;
  7.  
  8. typedef vector<int> vi;
  9. typedef vector<vector<int> > vvi;
  10.  
  11. void matar(int i, long long &ans, vi &dead, vi &lucro, vi &matador, vvi &mata){
  12.         if(!dead[i]){
  13.         queue<int> Q;
  14.         Q.push(i);
  15.         int cur;
  16.         while(!Q.empty()){
  17.             cur = Q.front();
  18.             Q.pop();
  19.             ans += lucro[matador[cur]];
  20.             dead[cur] = 1;
  21.             for(int m : mata[cur]) Q.push(m);
  22.         }
  23.         }
  24. }
  25.  
  26. int main() {
  27.     int n;
  28.     scanf("%d", &n);
  29.     vi f(n+1), p(n+1), m(n+1), lucro(n+1);
  30.     vector<long long> s(n+1);
  31.     vvi mata(n+1); // mata[i] = snacks que podem matar i
  32.     vi matador(n+1); // matador de i mais lucrativo
  33.     vi dead(n+1); // 1 = morreu
  34.     p[0] = 1000001;
  35.     for(int i = 1; i <= n; ++i) scanf("%d %d %d %I64d", &f[i], &p[i], &m[i], &s[i]);
  36.  
  37.     for(int i = 1; i <= n; ++i){
  38.             lucro[i] = m[f[i]] - p[i];
  39.             if(lucro[i] > 0){
  40.                     mata[f[i]].push_back(i);
  41.                     if(p[i] < p[matador[f[i]]]) matador[f[i]] = i;
  42.             }
  43.     }
  44.     long long ans = 0;
  45.     for(int i = 1; i <= n; ++i) if(!dead[i]) ans += (s[i] - 1)*(lucro[matador[i]]); // agora tudo 1
  46.     for(int i = 1; i <= n; ++i) if(!dead[i] && lucro[i] <= 0) matar(i, ans, dead, lucro, matador, mata);
  47.     for(int i = 1; i <= n; ++i){
  48.             if(!dead[i]){
  49.             // achar ciclo
  50.             unordered_set<int> S;
  51.             int a = i;
  52.             while(S.count(a)==0){
  53.                     S.insert(a);
  54.                     a = f[a];
  55.             }
  56.             vi ciclo;
  57.             ciclo.push_back(a);
  58.             int next = f[a];
  59.             while(next != a){
  60.                 ciclo.push_back(next);
  61.                 next = f[next];
  62.             }
  63.             int bad = 1;
  64.             int c = ciclo.size();
  65.             if(c==1) ans+= lucro[a];
  66.             else{
  67.             for(int j = 0; j < c && bad; ++j){
  68.                 if(matador[ciclo[j]]!=ciclo[(j-1+c)%c]){// pode matar geral..
  69.                     bad = 0;
  70.                     for(int v = (j-1+c)%c; v!=j; v = (v-1+c)%c) matar(ciclo[v], ans, dead, lucro, matador, mata);
  71.                     matar(ciclo[j], ans, dead, lucro, matador, mata);
  72.                 }
  73.             }
  74.             if(bad){// ciclo escroto..
  75.                 int otimo = 0;
  76.                 int curscore, curx;
  77.                 int second = 0;
  78.                 int minscore = p[0], minx = 0;
  79.                 for(int j = 0; j < c; ++j){
  80.                         second = 0;
  81.                         curscore = lucro[matador[ciclo[j]]];
  82.                         for(int x : mata[ciclo[j]]) if(x!=matador[ciclo[j]] && lucro[x] > second){
  83.                             second = lucro[x];
  84.                             curx = x;
  85.                         }
  86.                         curscore -= second;
  87.                         if(curscore < minscore){otimo = j; minscore = curscore; minx = curx;}
  88.                 }
  89.                 vi newmata; // tira o matador original..
  90.                 for(int x : mata[ciclo[otimo]]) if(x!=matador[ciclo[otimo]]) newmata.push_back(x);
  91.                 mata[ciclo[otimo]] = newmata; // muda o mata..
  92.                 matador[ciclo[otimo]] = minx; // agora pode matar tudo..
  93.                 for(int v = (otimo-1+c)%c; v!=otimo; v = (v-1+c)%c) matar(ciclo[v], ans, dead, lucro, matador, mata);
  94.                 matar(ciclo[otimo], ans, dead, lucro, matador, mata);
  95.             }
  96.             }
  97.             }
  98.     }
  99.     printf("%I64d", ans);
  100.     return 0;
  101. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement