赞
踩
一开始写的暴力合并 卡n^2过的不是正解
看正解是类似 虚拟点+树形DP的思路 很巧妙 记录一下
- #include<bits/stdc++.h>
- using namespace std;
- using ll = long long;
- using pii = pair<int,int>;
- #define int long long
- const int N = 3e5+10;
- const int inf = 0x3f3f3f3f;
- const int mod = 1e9+7;
- int gcd(int a,int b){return b?a:gcd(b,a%b);}
- int lcm(int a,int b){return a*b/gcd(a,b);}
- int qmi(int a,int b,int mod){int res=1;while(b){if(b&1)res=res*a%mod;b>>=1;a=a*a%mod;}return res;}
-
-
- int n,q,m;
- int p[N];
- int dp[N];
- int find(int x){
- if(x!=p[x])p[x] = find(p[x]);
- return p[x];
- }
- int e[N],ne[N],w[N],h[N],idx;
- void add(int a,int b,int c=0){
- e[idx] = b,ne[idx] = h[a],w[idx] = c,h[a] = idx++;
- }
-
-
- void dfs(int u,int fa){
- dp[u]+=dp[fa];
- for(int i=h[u];~i;i=ne[i]){
- int j = e[i];
- dfs(j,u);
- }
- }
-
-
- void solve()
- {
- cin>>n>>m;
- int root = n+1;
- memset(h,-1,sizeof h);
- for(int i=1;i<=2*n+10;++i)p[i] = i;
- while(m--){
- int op,a,b;cin>>op>>a>>b;
- if(op==1){
- int pa = find(a),pb = find(b);
- if(pa==pb)continue;
- p[pa] = root;
- p[pb] = root;
- add(root,pa);
- add(root,pb);
- ++root;
- }else{
- dp[find(a)]+=b;
- }
- }
-
- for(int i=n+1;i<root;++i)if(find(i)==i)dfs(i,0);
- for(int i=1;i<=n;i++)cout<<dp[i]<<" ";
-
-
-
- }
-
- signed main()
- {
- ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
- int _;
- //cin>>_;
- _ = 1;
- while(_--)solve();
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。