[CF160D]Edges in MST (最小生成树+LCA+差分)
待填坑
Code
//CF160D Edges in MST //Apr,4th,2018 //树上差分+LCA+MST #include<cstdio> #include<iostream> #include<vector> #include<algorithm> #include<cstring> using namespace std; long long read() { long long x=0,f=1; char c=getchar(); while(!isdigit(c)){if(c=='-') f=-1;c=getchar();} while(isdigit(c)){x=x*10+c-'0';c=getchar();} return x*f; } const int N=100000+1000; struct line { int s,t,w1,w,ans,no; }e[N]; struct edge { int t,w,no; }; bool cmp(line a,line b) { return a.w1<b.w1; } bool cmp2(line a,line b) { return a.no<b.no; } vector <edge> r[N]; struct mrk { int num,count; }; vector <mrk> mk[N]; int n,m; bool IsOnMST[N]; int fa[N][21],mx[N][21],d[N],mark[N]; bool visited[N]; void dfs(int now,int depth) { visited[now]=true; d[now]=depth; for(int i=1;i<=20;i++) { fa[now][i]=fa[fa[now][i-1]][i-1]; mx[now][i]=max(mx[now][i-1],mx[fa[now][i-1]][i-1]); } int to=r[now].size(); for(int i=0;i<to;i++) if(visited[r[now][i].t]==false) { fa[r[now][i].t][0]=now; mx[r[now][i].t][0]=r[now][i].w; dfs(r[now][i].t,depth+1); } } int LCA(int x,int y,int &MAX) { if(d[x]<d[y]) swap(x,y); for(int i=20;i>=0;i--) if(d[fa[x][i]]>=d[y]) { MAX=max(MAX,mx[x][i]); x=fa[x][i]; } if(x==y) return x; for(int i=20;i>=0;i--) if(fa[x][i]!=fa[y][i]) { MAX=max(MAX,mx[x][i]); MAX=max(MAX,mx[y][i]); x=fa[x][i],y=fa[y][i]; } MAX=max(MAX,mx[x][0]); MAX=max(MAX,mx[y][0]); return fa[x][0]; } int FA[N]; inline int FindFather(int x) { if(FA[x]==0) return x; return FA[x]=FindFather(FA[x]); } void MST() { sort(e+1,e+1+m,cmp); for(int i=1;i<=m;i++) if(e[i].w1!=e[i-1].w1) e[i].w=e[i-1].w+1; else e[i].w=e[i-1].w; int tot=0; for(int i=1;i<=m;i++) { int f1=FindFather(e[i].s),f2=FindFather(e[i].t); if(f1!=f2) { FA[f1]=f2; r[e[i].s].push_back((edge){e[i].t,e[i].w,i}); r[e[i].t].push_back((edge){e[i].s,e[i].w,i}); IsOnMST[i]=true; tot++; e[i].ans=2; } if(tot==n-1) break; } } void dfs2(int now) { visited[now]=true; for(int i=0;i<int(r[now].size());i++) if(visited[r[now][i].t]==false) { int stm=mark[r[now][i].w]; dfs2(r[now][i].t); if(mark[r[now][i].w]-stm>0) e[r[now][i].no].ans=1; } for(int i=0;i<int(mk[now].size());i++) mark[mk[now][i].num]+=mk[now][i].count; } int main() { n=read(),m=read(); for(int i=1;i<=n;i++) mk[i].reserve(4), r[i].reserve(4); for(int i=1;i<=m;i++) e[i].s=read(),e[i].t=read(),e[i].w1=read(),e[i].no=i; MST(); dfs(1,1); for(int i=1;i<=m;i++) if(IsOnMST[i]==false) { int MAX=0,lca=LCA(e[i].s,e[i].t,MAX); if(MAX==e[i].w) { e[i].ans=1; mk[e[i].s].push_back((mrk){MAX,1}); mk[e[i].t].push_back((mrk){MAX,1}); mk[lca].push_back((mrk){MAX,-2}); } } memset(visited,0,sizeof visited); dfs2(1); sort(e+1,e+1+m,cmp2); for(int i=1;i<=m;i++) if(e[i].ans==0) printf("none\n"); else if(e[i].ans==1) printf("at least one\n"); else printf("any\n"); return 0; }
自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。