Submission #527342

#TimeUsernameProblemLanguageResultExecution timeMemory
527342jamielimPipes (CEOI15_pipes)C++14
70 / 100
1518 ms17288 KiB
#include <bits/stdc++.h> using namespace std; #define fi first #define se second #define mp make_pair #define pb emplace_back #define ALL(x) x.begin(),x.end() #define SZ(x) (int)x.size() typedef long long ll; typedef pair<int,int> ii; typedef pair<ii,ii> i4; const int MOD=1000000007; const int INF=1012345678; const ll LLINF=1012345678012345678LL; const double PI=3.1415926536; const double EPS=1e-14; const int MAXN=100005; int n,m; int par[MAXN],par2[MAXN]; int root(int x){return par[x]=(par[x]==x?x:root(par[x]));} int root2(int x){return par2[x]=(par2[x]==x?x:root2(par2[x]));} vector<int> adj[MAXN]; // only stores a tree int p[MAXN][18]; bool marking[MAXN][18]; int depth[MAXN]; void dfs(int x,int par){ if(p[x][0]!=0)return; p[x][0]=par; if(par!=0)depth[x]=depth[par]+1; for(int i:adj[x]){ if(i==par)continue; if(p[i][0]==0)dfs(i,x); } } void lca(int a,int b){ //printf("lca %d %d\n",a,b); if(a==b)return;// a; if(depth[a]<depth[b])swap(a,b); for(int i=17;i>=0;i--){ if(p[a][i]!=0&&depth[p[a][i]]>=depth[b]){ marking[a][i]=1; a=p[a][i]; } } if(a==b)return;// a; for(int i=17;i>=0;i--){ if(p[a][i]!=p[b][i]){ marking[a][i]=1; marking[b][i]=1; a=p[a][i]; b=p[b][i]; } } marking[a][0]=1; marking[b][0]=1; return;// p[a][0]; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)par[i]=par2[i]=i; int a,b; ii edges[n];int idx=0; for(int i=0;i<m;i++){ scanf("%d%d",&a,&b); //if a,b are in different trees, merge the two trees int ra=root(a),rb=root(b); if(ra!=rb){ par[ra]=rb; adj[a].pb(b); adj[b].pb(a); continue; } //otherwise, take note that later we have to get rid of the entire cycle int r2a=root2(a),r2b=root2(b); if(r2a!=r2b){ par2[r2a]=par2[r2b]; edges[idx++]=mp(a,b); } } // preprocess the forest for(int i=1;i<=n;i++){ if(depth[i]==0)dfs(i,0); } for(int i=1;i<18;i++){ for(int j=1;j<=n;j++){ p[j][i]=p[p[j][i-1]][i-1]; } } // for every cycle we want to remove, find the lca, mark all the visited 2kdecomps as gone for(int i=0;i<idx;i++){ lca(edges[i].fi,edges[i].se); } // then finally propagate all the markings down for(int i=17;i>=1;i--){ for(int j=1;j<=n;j++){ if(marking[j][i]){ marking[j][i-1]=1; marking[p[j][i-1]][i-1]=1; } } } for(int i=1;i<=n;i++){ if(marking[i][0])continue; for(int j:adj[i]){ if(depth[j]<depth[i]){ // j is i's parent printf("%d %d\n",j,i); break; } } } }

Compilation message (stderr)

pipes.cpp: In function 'int main()':
pipes.cpp:63:7: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   63 |  scanf("%d%d",&n,&m);
      |  ~~~~~^~~~~~~~~~~~~~
pipes.cpp:68:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   68 |   scanf("%d%d",&a,&b);
      |   ~~~~~^~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...