FHVirus

Untitled

May 4th, 2021
223
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.69 KB | None | 0 0
  1. // Knapsack DP is harder than FFT.
  2. #include<bits/stdc++.h>
  3. using namespace std;
  4. typedef int64_t ll; typedef pair<int,int> pii; typedef pair<ll,ll> pll;
  5. #define ff first
  6. #define ss second
  7. #define pb emplace_back
  8. #define FOR(i,n) for(int i=0;i<(n);++i)
  9. #define FOO(i,a,b) for(int i=(a);i<=int(b);++i)
  10. #define OOF(i,a,b) for(int i=(a);i>=int(b);--i)
  11. #define AI(x) begin(x),end(x)
  12. template<class I>bool chmax(I&a,I b){return a<b?(a=b,true):false;}
  13. template<class I>bool chmin(I&a,I b){return b<a?(a=b,true):false;}
  14. inline ll cdiv(ll x,ll m){return x/m+(x%m?(x<0)^(m>0):0);}
  15. #ifdef OWO
  16. #define safe cerr<<"\033[1;32m"<<__PRETTY_FUNCTION__<<" - "<<__LINE__<<" JIZZ\033[0m\n"
  17. #define debug(args...) SDF(#args, args)
  18. #define OIU(args...) ostream& operator<<(ostream&O,args)
  19. #define LKJ(S,B,E,F) template<class...T>OIU(S<T...>s){O<<B;int c=0;for(auto i:s)O<<(c++?", ":"")<<F;return O<<E;}
  20. LKJ(vector,'[',']',i)LKJ(deque,'[',']',i)LKJ(set,'{','}',i)LKJ(multiset,'{','}',i)LKJ(unordered_set,'{','}',i)LKJ(map,'{','}',i.ff<<':'<<i.ss)LKJ(unordered_map,'{','}',i.ff<<':'<<i.ss)
  21. template<class T,size_t N>OIU(array<T,N>a){return O<<vector<T>(AI(a));}template<class...T>OIU(pair<T...>p){return O<<'('<<p.ff<<','<<p.ss<<')';}template<class...T>OIU(tuple<T...>t){return O<<'(',apply([&O](T...s){int c=0;(...,(O<<(c++?", ":"")<<s));},t),O<<')';}
  22. template<class...T>void SDF(const char* s,T...a){int c=sizeof...(T);if(!c){cerr<<"\033[1;32mvoid\033[0m\n";return;}(cerr<<"\033[1;32m("<<s<<") = (",...,(cerr<<a<<(--c?", ":")\033[0m\n")));}
  23. #else
  24. #pragma GCC optimize("Ofast")
  25. #define safe ((void)0)
  26. #define debug(...) ((void)0)
  27. #endif
  28. const ll inf = 1e9, INF = 4e18;
  29.  
  30. struct Solver{
  31.     static const int inf = 1e9;
  32.     struct route{
  33.         int dis, head, tail;
  34.         route(int d = inf, int h = -1, int t = -1):
  35.             dis(d), head(h), tail(t){}
  36.         bool operator<(const route &rhs){
  37.             if(dis != rhs.dis) return dis < rhs.dis;
  38.             return tail < rhs.tail;
  39.         }
  40.     };
  41.     struct eek{
  42.         // store best two ans
  43.         // with different color
  44.         route one, two;
  45.         eek(): one(), two(){}
  46.         eek(route a, route b): one(a), two(b){}
  47.         void upd(route cur){
  48.             if(cur < one) swap(cur, one);
  49.             // if best and cur are in
  50.             // same color, then discard
  51.             // the worse one
  52.             if(cur.tail == one.tail) return;
  53.             if(cur < two) swap(cur, two);
  54.         }
  55.     };
  56.     eek merge(eek a, eek b){
  57.         eek anss;
  58.         for(route x: {a.one, a.two}) for(route y: {b.one, b.two})
  59.             if(x.tail != y.head)
  60.                 anss.upd(route(x.dis + y.dis, x.head, y.tail));
  61.         return anss;
  62.     }
  63.  
  64.     int n;
  65.     vector<vector<eek>> dp;
  66.     map<string, int> mp;
  67.  
  68.     Solver(){}
  69.     void init(int _n){
  70.         n = _n;
  71.         dp.assign(n, vector<eek>(n));
  72.         mp.clear();
  73.     }
  74.     void addEdge(int u, int v, int c){
  75.         route e(1, c, c);
  76.         dp[u][v].upd(e);
  77.         dp[v][u].upd(e);
  78.     }
  79.     void fw(){
  80.         for(int k = 0; k < n; ++k)
  81.             for(int i = 0; i < n; ++i)
  82.                 for(int j = 0; j < n; ++j){
  83.                     eek tmp = merge(dp[i][k], dp[k][j]);
  84.                     dp[i][j].upd(tmp.one);
  85.                     dp[i][j].upd(tmp.two);
  86.                 }
  87.     }
  88.  
  89.     void solve(){
  90.         int n, m, q;
  91.         cin >> n >> m;
  92.         init(n);
  93.         for(int i = 0; i < n; ++i){
  94.             string s; cin >> s;
  95.             mp[s] = i;
  96.         }
  97.         for(; m; --m){
  98.             int u, v, c;
  99.             cin >> u >> v >> c;
  100.             addEdge(u, v, c);
  101.         }
  102.         fw();
  103.         fw();
  104.         fw();
  105.         for(cin >> q; q; --q){
  106.             string a, b; int u, v;
  107.             cin >> a >> b;
  108.             bool no = false;
  109.             if(mp.count(a)) u = mp[a]; else no = true;
  110.             if(mp.count(b)) v = mp[b]; else no = true;
  111.             if(dp[u][v].one.dis == inf) no = true;
  112.            
  113.             if(no) cout << "HweiBuHweiChiShiTaShi...\n";
  114.             else cout << dp[u][v].one.dis << '\n';
  115.  
  116.             if(!no) assert(dp[u][v].one.dis == dp[v][u].one.dis);
  117.         }
  118.     }
  119. } solver;
  120.  
  121. int32_t main(){
  122.     ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
  123.     solver.solve();
  124.     return 0;
  125. }
  126.  
Add Comment
Please, Sign In to add comment