Submission #64463

#TimeUsernameProblemLanguageResultExecution timeMemory
64463TadijaSebezMin-max tree (BOI18_minmaxtree)C++11
58 / 100
1070 ms45372 KiB
#include <stdio.h> #include <vector> #include <algorithm> #include <queue> #include <map> using namespace std; #define pb push_back const int N=70050; const int M=N*2; const int inf=1e9+7; int min(int a, int b){ return a>b?b:a;} int max(int a, int b){ return a>b?a:b;} namespace Dinic { int s,t; vector<int> G[M]; struct Edge { int u,v,c; Edge(int a, int b, int d){ u=a,v=b,c=d;} }; vector<Edge> edges; void AddEdge(int u, int v, int c) { G[u].pb(edges.size()); edges.pb(Edge(u,v,c)); G[v].pb(edges.size()); edges.pb(Edge(v,u,0)); } int was[M],dist[M]; queue<int> q; bool BFS() { int i; for(i=s;i<=t;i++) was[i]=0,dist[i]=inf; dist[s]=0; q.push(s); while(q.size()) { int u=q.front();q.pop(); for(i=0;i<G[u].size();i++) { int e=G[u][i]; int v=edges[e].v; int c=edges[e].c; if(c && dist[v]>dist[u]+1) { dist[v]=dist[u]+1; q.push(v); } } } return dist[t]!=inf; } int Cut(int u, int flow) { if(u==t) return flow; if(dist[u]>dist[t] || !flow) return 0; int ans=0; for(;was[u]<G[u].size();was[u]++) { int e=G[u][was[u]]; int v=edges[e].v; int c=edges[e].c; if(!c || dist[v]!=dist[u]+1) continue; int cut=Cut(v,min(flow,c)); flow-=cut; ans+=cut; edges[e].c-=cut; edges[e^1].c+=cut; if(!flow) return ans; } return ans; } int MaxFlow() { int Flow=0; while(BFS()) Flow+=Cut(s,inf); return Flow; } } vector<int> E[N]; int par[N][17],Min[N][17],Max[N][17],dep[N]; void DFS(int u, int p) { int i; for(i=0;i<17;i++) Min[u][i]=inf,Max[u][i]=-inf; par[u][0]=p; dep[u]=dep[p]+1; for(i=1;i<17;i++) par[u][i]=par[par[u][i-1]][i-1]; for(i=0;i<E[u].size();i++) { int v=E[u][i]; if(v!=p) DFS(v,u); } } int LCA(int u, int v) { if(dep[u]<dep[v]) return LCA(v,u); int i; for(i=16;~i;i--) if(dep[par[u][i]]>=dep[v]) u=par[u][i]; for(i=16;~i;i--) if(par[u][i]!=par[v][i]) u=par[u][i],v=par[v][i]; return v==u?v:par[v][0]; } void AddMax(int u, int lca, int x) { int i; for(i=16;~i;i--) { if(dep[par[u][i]]>=dep[lca]) { Max[u][i]=max(Max[u][i],x); u=par[u][i]; } } } void AddMin(int u, int lca, int x) { int i; for(i=16;~i;i--) { if(dep[par[u][i]]>=dep[lca]) { Min[u][i]=min(Min[u][i],x); u=par[u][i]; } } } void Push(int n) { int j,i; for(j=16;j;j--) { for(i=1;i<=n;i++) { Max[i][j-1]=max(Max[i][j-1],Max[i][j]); Max[par[i][j-1]][j-1]=max(Max[par[i][j-1]][j-1],Max[i][j]); Min[i][j-1]=min(Min[i][j-1],Min[i][j]); Min[par[i][j-1]][j-1]=min(Min[par[i][j-1]][j-1],Min[i][j]); } } } map<int,int> id; int sol[N],weg[N]; int main() { int n,i,u,v,m,z,c;char t; scanf("%i",&n); for(i=1;i<n;i++) scanf("%i %i",&u,&v),E[u].pb(v),E[v].pb(u); DFS(1,0); scanf("%i",&m); for(i=1;i<=m;i++) { scanf("\n%c %i %i %i",&t,&u,&v,&z); id[z]=i;weg[i]=z; int lca=LCA(u,v); if(t=='M') AddMin(u,lca,z),AddMin(v,lca,z); else AddMax(u,lca,z),AddMax(v,lca,z); } Push(n); Dinic::s=0; Dinic::t=n+m+1; for(i=1;i<=n;i++) { sol[i]=1; Dinic::AddEdge(Dinic::s,i,1); if(id.count(Min[i][0])) Dinic::AddEdge(i,id[Min[i][0]]+n,1),sol[i]=Min[i][0]; if(id.count(Max[i][0])) Dinic::AddEdge(i,id[Max[i][0]]+n,1),sol[i]=Max[i][0]; } for(i=1;i<=m;i++) Dinic::AddEdge(i+n,Dinic::t,1); Dinic::MaxFlow(); for(i=0;i<Dinic::edges.size();i++) { u=Dinic::edges[i].u; v=Dinic::edges[i].v; c=Dinic::edges[i].c; if(!c && u>0 && u<=n && v>n && v<=n+m) { sol[u]=weg[v-n]; } } for(i=2;i<=n;i++) printf("%i %i %i\n",i,par[i][0],sol[i]); return 0; }

Compilation message (stderr)

minmaxtree.cpp: In function 'bool Dinic::BFS()':
minmaxtree.cpp:41:13: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    for(i=0;i<G[u].size();i++)
            ~^~~~~~~~~~~~
minmaxtree.cpp: In function 'int Dinic::Cut(int, int)':
minmaxtree.cpp:60:14: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(;was[u]<G[u].size();was[u]++)
        ~~~~~~^~~~~~~~~~~~
minmaxtree.cpp: In function 'void DFS(int, int)':
minmaxtree.cpp:91:11: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(i=0;i<E[u].size();i++)
          ~^~~~~~~~~~~~
minmaxtree.cpp: In function 'int main()':
minmaxtree.cpp:172:11: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(i=0;i<Dinic::edges.size();i++)
          ~^~~~~~~~~~~~~~~~~~~~
minmaxtree.cpp:148:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%i",&n);
  ~~~~~^~~~~~~~~
minmaxtree.cpp:149:50: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  for(i=1;i<n;i++) scanf("%i %i",&u,&v),E[u].pb(v),E[v].pb(u);
                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~
minmaxtree.cpp:151:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%i",&m);
  ~~~~~^~~~~~~~~
minmaxtree.cpp:154:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("\n%c %i %i %i",&t,&u,&v,&z);
   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...