제출 #1202530

#제출 시각아이디문제언어결과실행 시간메모리
12025308pete8Min-max tree (BOI18_minmaxtree)C++20
0 / 100
143 ms74132 KiB
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define f first
#define s second
#define pii pair<int,int>
#define ppii pair<int,pii>
#define vi vector<int>
#define pb push_back
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define F(n) for(int i=0;i<n;i++)
#define lb lower_bound
#define ub upper_bound
#define fastio ios::sync_with_stdio(false);cin.tie(NULL);
#pragma GCC optimize("O3")
#pragma GCC target("avx2,popcnt,lzcnt,abm,bmi,bmi2,fma,tune=native,sse,sse2,sse3")
using namespace std;
#define int long long
const int mod=1e9+7,mxn=2e5+5,inf=1e18,minf=-1e18,lg=31,Mxn=6e6,base=131;
//#undef int
int n,k,m,q,L;
void setIO(string name){
	ios_base::sync_with_stdio(0); cin.tie(0);
	freopen((name+".in").c_str(),"r",stdin);
	freopen((name+".out").c_str(),"w",stdout);
}
vector<int>adj[mxn+10];
int up[mxn+10][lg+1],h[mxn+10],pa[mxn+10];
void dfs(int cur,int p){
	for(auto i:adj[cur])if(i!=p){
		h[i]=h[cur]+1;
		pa[i]=cur;
		dfs(i,cur);
		up[i][0]=cur;
	}
}
int lca(int a,int b){
	if(h[a]<h[b])swap(a,b);
	int k=h[a]-h[b];
	for(int i=0;i<=lg;i++)if(k&(1LL<<i))a=up[a][i];
	if(a==b)return a;
	for(int i=lg;i>=0;i--)if(up[a][i]!=up[b][i]){
		a=up[a][i];
		b=up[b][i];
	}
	return up[a][0];
}
priority_queue<pii>T[2][mxn+10];
int H[mxn+10],val[mxn+10];
int P[mxn+10][2];
void getpa(int cur,int p){
	for(auto i:adj[cur])if(i!=p){
		getpa(i,cur);
		for(int j=0;j<2;j++)if(T[j][i].size()>T[j][cur].size()){
			swap(T[j][i],T[j][cur]);
			while(!T[j][i].empty())T[j][cur].push(T[j][i].top()),T[j][i].pop();
		}
	}
	for(int j=0;j<2;j++){
		while(!T[j][cur].empty()&&H[T[j][cur].top().s]>=h[cur])T[j][cur].pop();
		if(T[j][cur].size())P[cur][j]=T[j][cur].top().s;
		
	}
}
struct edge{int v,flow,cap;};
struct dinic{
    int lvl[mxn+10],at[mxn+10];
    vector<edge>E;
    vector<int>go[mxn+10];
    int scaling=0,lim;
    //with or without scaling?
    void addedge(int u,int v,int cap){
        //add edge and the corresponding residual edge
        go[u].pb(E.size()),E.pb({v,0,cap});
        go[v].pb(E.size()),E.pb({u,0,0});
    }
    bool bfs(int S,int T){
        //get leveled graph
        for(int i=0;i<=n+q+1;i++)lvl[i]=-1,at[i]=0;
        lvl[S]=0;
        queue<int>q;
        q.push(S);
        while(!q.empty()){
            int cur=q.front();
            q.pop();
            for(auto i:go[cur]){
                edge x=E[i];
                if(lvl[x.v]<0&&x.flow<x.cap&&(!scaling||x.cap-x.flow>=lim)){
                    lvl[x.v]=lvl[cur]+1;
                    q.push(x.v);  
                }
            }
        }
        return lvl[T]>=0;
    }
    int dfs(int cur,int T,int F){
        //push flow
        if(cur==T)return F;
        for(at[cur];at[cur]<go[cur].size();at[cur]++){
            edge& x=E[go[cur][at[cur]]];
            if(lvl[x.v]!=lvl[cur]+1||x.flow==x.cap)continue;
            int df=dfs(x.v,T,min(F,x.cap-x.flow));
            if(df){
                x.flow+=df;
                E[go[cur][at[cur]]^1].flow-=df;
                return df;
            }
        }
        return 0;
    }
    int maxflow(int S,int T){
        int ans=0;
        for(lim=((scaling)?(1LL<<30):1);lim>0;lim>>=1){
            while(bfs(S,T)){
                while(int df=dfs(S,T,inf))ans+=df;
            }
        }
        return ans;
    }
}t;
int32_t main(){
	fastio
	cin>>n;
	for(int i=0;i<n-1;i++){
		int a,b;cin>>a>>b;
		adj[a].pb(b);
		adj[b].pb(a);
	}
	for(int i=0;i<=lg;i++)up[1][i]=1;
	dfs(1,-1);
	for(int j=1;j<=lg;j++)for(int i=1;i<=n;i++)up[i][j]=up[up[i][j-1]][j-1];
	cin>>q;
	for(int i=1;i<=q;i++){
		char x;cin>>x;
		int a,b,c;cin>>a>>b>>c;
		val[i]=c;
		int node=lca(a,b);
		H[i]=h[node];
		int k=(x=='M');
		T[k][a].push({c*((k)?-1:1),i});
		T[k][b].push({c*((k)?-1:1),i});
	}
	getpa(1,-1);
	for(int i=1;i<=n;i++){

		for(int j=0;j<2;j++)if(P[i][j])t.addedge(i,n+P[i][j],1);
		t.addedge(0,i,1);
	}
	for(int i=n+1;i<=n+q;i++)t.addedge(i,n+q+1,1);
	t.maxflow(0,n+q+1);
	for(int i=2;i<=n;i++){
		int choose=0,k=0;
		for(auto j:t.go[i]){
			edge x=t.E[j];
			if(x.flow>0){
				if(choose)assert(0);
				choose=P[i][k];
			}
			k++;
		}
		cout<<i<<" "<<pa[i]<<" "<<val[choose]<<"\n";
	}
}
/*
*/

컴파일 시 표준 에러 (stderr) 메시지

minmaxtree.cpp: In function 'void setIO(std::string)':
minmaxtree.cpp:25:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   25 |         freopen((name+".in").c_str(),"r",stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
minmaxtree.cpp:26:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   26 |         freopen((name+".out").c_str(),"w",stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...