《省赛模拟赛补》
C题:
比赛的时候已经想到了统计最底层的每个序列的出现次数,但是一开始想的是建图之后dfs处理,但是发现很难处理出来。
其实正确的思路是拓扑排序去处理次数。
我们在最后建图完成之后,倒着从n回去拓扑即可。
但是这里有个坑点,就是一开始统计入度可能是不正确的。
例如:3(1 , 2), 4 (1 ,2),3是1,2的父节点,4是1,2的父节点,这样的话,我们拓扑的时候1,2的入度就不可能减到2了,因为我们最终的序列是s4,所以我们只去考虑和4相关。
所以对于入度的统计,我们需要从终点bfs去重新计算入度,然后再拓扑即可。
这里cnt忘开longlong被卡了一会。。
最后就是复杂度的证明:
可以发现,拓扑和bfs的复杂度显然也就1e6左右,主要是可能会觉得最后map统计那里会T,但是实际上,map统计那里,我们只是进行了一个对输入的重新遍历(加了个log的复杂度,还是很快的),如果输入不会T,显然这里也不会。
(输入怎么可能会T~~)
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<double,int> pii; const int N = 1e6+5; const int M = 1e6+5; const LL Mod = 1e9+7; #define rg register #define pi acos(-1) #define INF 1e18 #define CT0 cin.tie(0),cout.tie(0) #define IO ios::sync_with_stdio(false) #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read(){ LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();} return x*f; } void print(int x){ if(x < 0){x = -x;putchar('-');} if(x > 9) print(x/10); putchar(x%10+'0'); } } using namespace FASTIO; vector<int> a[N],G[N]; int vis[N],id[N]; LL cnt[N],in[N]; void bfs(int n) { queue<int> Q; Q.push(n); vis[n] = 1; while(!Q.empty()) { int u = Q.front(); Q.pop(); for(auto v : G[u]) { in[v]++; if(!vis[v]) vis[v] = 1,Q.push(v); } } } void solve(int n) { queue<int> Q; Q.push(n); cnt[n] = 1; while(!Q.empty()) { int u = Q.front(); Q.pop(); for(auto v : G[u]) { in[v]--; cnt[v] += cnt[u]; if(in[v] == 0) Q.push(v); } } unordered_map<int,LL> mp; LL mx = -1,sum = 0; for(rg int i = 1;i <= n;++i) { if(id[i] == 2 || cnt[i] == 0) continue; for(auto v : a[i]) { mp[v] += cnt[i]; sum += cnt[i]; mx = max(mx,mp[v]); } } LL ma = sum - mx; printf("%lld\n",mx <= ma ? sum : ma * 2); } int main() { int ca;ca = read(); while(ca--) { int n;n = read(); for(rg int i = 1;i <= n;++i) in[i] = 0,cnt[i] = 0,G[i].clear(),a[i].clear(),vis[i] = 0; for(rg int i = 1;i <= n;++i) { int idd;idd = read(); id[i] = idd; if(idd == 1) { int k;k = read(); while(k--) { int x;x = read(); a[i].push_back(x); } } else { int x,y;x = read(),y = read(); G[i].push_back(x); G[i].push_back(y); } } bfs(n); solve(n); } system("pause"); return 0; } /* 4 4 1 2 2 2 1 2 2 4 2 1 2 2 1 2 */