【[Ynoi2015]我回來了】
阿新 • • 發佈:2019-02-11
push_back urn har stk 其中 end put cout noi2015
人生第一道ynoi題,感覺大家是不是被ynoi的標簽嚇到了啊= =,此題的難度個人覺得不到黑題。
正文部分
\(bitset\)+類似一個\(dp\)的東西亂搞。
定義\(f[u][x]\)的含義是從第\(u\)號點開始所有路徑長度不超過\(x\)的集合,這個東西顯然我們是可以用\(bitset\)去維護的。
接著我們考慮在這個\(f\)數組上動一些手腳
對於任何一個\(f[i][j]\),其\(f[i][dis[j]][j]=1\)
這個東西是固定的,為什麽?因為是最短路,到達了這個路徑的最後一步一定是這個點,於是必定為\(1\)。
繼續考慮轉移\(f[i][j]\)
不難發現:\(f[i][j]=f[i][j]|f[i][j-1]\)
其中\(j\)表示的是一個距離,為什麽可以這樣轉移?因為對於任何一個\(dis\),其\(dis-1\)包含了\(dis-2\),\(dis-2\)包含了\(dis-3\)...,於是我們可以大膽的直接或上就行了。
至於最短路,因為權值都相等,所以直接可以寫\(1\)個\(bfs\)這裏省略。我不會告訴你我dij都寫完了才發現了logn的大常數。
My Code:
#include <bits/stdc++.h> #define il inline #define gc getchar #define pc putchar #define pb push_back const int MAXN = 1010; const int GINF = 1001; using namespace std; namespace IO { il int read() { int res = 0;char c;bool sign = 0; for(c = gc();!isdigit(c);c = gc()) sign |= c == ‘-‘; for(;isdigit(c);c = gc()) res = (res << 1) + (res << 3) + (c ^ 48); return sign ? -res : res; } il void write(int x) { if(x < 0) x = -x,pc(‘-‘); int stk[20];stk[0] = 0; for(;x;x /= 10) stk[++stk[0]] = x % 10; for(int i = stk[0];i >= 1;i--) pc(stk[i] + 48); return; } il void writeln(int x) { write(x);pc(‘\n‘); } } using IO::read;using IO::write;using IO::writeln; int n,m,i,j,k,q,_i; bitset<MAXN> f[MAXN][MAXN]; int dis[MAXN];vector<int>g[MAXN]; il void readdEdge(int u,int v) { g[u].pb(v);g[v].pb(u); } il void bfs(int S) { int i; for(i = 1;i <= n;i++) dis[i] = GINF;dis[S] = 0; queue<int>Q;Q.push(S); while(!Q.empty()) { int u = Q.front();Q.pop(); for(i = 0;i < g[u].size();i++) { int to = g[u][i]; if(dis[u] + 1 < dis[to]) { dis[to] = dis[u] + 1; Q.push(to); } } } // cout << endl << S; // for(i = 1;i <= n;i++) cout << dis[i] << ‘ ‘; // cout << endl; return; } int main() { n = read();m = read();q = read(); for(i = 1;i <= m;i++) { int u = read(),v = read(); readdEdge(u,v); } for(i = 1;i <= n;i++) { bfs(i); for(j = 1;j <= n;j++) f[i][dis[j]].set(j); for(j = 1;j <= n;j++) f[i][j] |= f[i][j - 1]; } for(_i = 1;_i <= q;_i++) { int T = read(),_j;bitset<MAXN> res; for(_j = 1;_j <= T;_j++) { int x = read(),y = read(); res |= f[x][y]; } writeln(res.count()); } return 0; }
【[Ynoi2015]我回來了】