hdu5409
对于这道题,一开始看了题解,信誓旦旦的觉得我能写,结果发现超时,虽然继续找题解,但是心里仍然吐槽,怎么会超时?看了别人写的以后,才发现有更巧妙的办法,不用对于每条边都进行一个搜索,以n在的那个块建树就可以了,真的不能太死板!
代码参考:http://www.cnblogs.com/oneshot/p/4748840.html
(今天比赛发吃的,我们没比赛,然后就没有吃的)
2015.8.29:
是我记忆太好呢?还是我这道题虐我太深,我对它爱得深沉呢?好吧,肯定是因为刚做过,所以这道题回忆时思路挺流畅的。希望有一天能不看题解就能写出来,大神是要一万个小时才能练成,是不是?那些大神从小学就开始敲代码?我只能说,从小我就喜欢吃
#include<stdio.h> #include<string.h> #include<iostream> using namespace std; #define N 100010 int head[N],to[2*N],nextedge[2*N],id[2*N]; int head2[N],to2[2*N],nextedge2[2*N]; int w[N]; int edge[N][2]; int ans[N][2]; int cou; int dp[N][2]; int timemark[N]; int minfro[N]; int fa[N]; int dp2[N]; int bl[N]; int time; int num; int maxnum; void add(int a,int b,int tempid){ to[cou]=b;nextedge[cou]=head[a];id[cou]=tempid;head[a]=cou++; } void add2(int a,int b){ to2[cou]=b;nextedge2[cou]=head2[a];head2[a]=cou++; } void dfs(int u,int tempfa,int faedge){ timemark[u]=++time; minfro[u]=time; dp[u][0]=0; dp[u][1]=0; fa[u]=tempfa; for(int i=head[u];i!=-1;i=nextedge[i]){ int v=to[i]; if(v==tempfa){ continue; } else if(dp[v][0]!=-1){ minfro[u]=minfro[u]>timemark[v]?timemark[v]:minfro[u]; ans[id[i]][0]=0; ans[id[i]][1]=0; } else{ dfs(v,u,id[i]); int tempdpv=v>dp[v][0]?v:dp[v][0]; if(tempdpv>dp[u][0]){ dp[u][1]=dp[u][0]; dp[u][0]=tempdpv; } else if(tempdpv>dp[u][1]){ dp[u][1]=tempdpv; } minfro[u]=minfro[u]>minfro[v]?minfro[v]:minfro[u]; } } if(minfro[u]<timemark[u]){ ans[faedge][0]=0; ans[faedge][1]=0; } return; } void dfs2(int u,int fa){ bl[u]=num; maxnum=maxnum>u?maxnum:u; for(int i=head[u];i!=-1;i=nextedge[i]){ int v=to[i]; if(v==fa){ continue; } else if(ans[id[i]][0]){ continue; } else if(bl[v]==-1){ dfs2(v,u); } } return; } void dfs3(int u,int fa){ //printf("wo shi da hao ren"); dp2[u]=w[u]; //printf("%d %d\n",u,w[u]); for(int i=head2[u];i!=-1;i=nextedge2[i]){ int v=to2[i]; if(v==fa){ continue; } else{ dfs3(v,u); dp2[u]=(dp2[u]>dp2[v]?dp2[u]:dp2[v]); } } return; } int main(){ int t; int n,m; int a,b; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); memset(head,-1,sizeof(head)); memset(ans,-1,sizeof(ans)); memset(dp,-1,sizeof(dp)); cou=0; for(int i=0;i<m;i++){ scanf("%d%d",&a,&b); add(a,b,i); add(b,a,i); edge[i][0]=a; edge[i][1]=b; } time=0; dfs(1,-1,-1); num=0; memset(bl,-1,sizeof(bl)); for(int i=1;i<=n;i++){ if(bl[i]==-1){ num++; maxnum=i; dfs2(i,-1); w[num]=maxnum; } } cou=0; memset(head2,-1,sizeof(head2)); for(int i=0;i<m;i++){ if(ans[i][0]){ int u=bl[edge[i][0]]; int v=bl[edge[i][1]]; add2(u,v); add2(v,u); } } for(int i=1;i<=num;i++){ if(w[i]==n){ dfs3(i,-1); break; } } /*for(int i=1;i<=num;i++){ printf("%d %d %d\n",i,w[i],dp2[i]); }*/ for(int i=0;i<m;i++){ if(ans[i][0]){ int u=bl[edge[i][0]]; int v=bl[edge[i][1]]; int temp=dp2[u]>dp2[v]?dp2[v]:dp2[u]; ans[i][0]=temp; ans[i][1]=temp+1; } printf("%d %d\n",ans[i][0],ans[i][1]); } } return 0; }
附上超时的代码,作纪念。
#include<stdio.h> #include<string.h> #include<iostream> using namespace std; #define N 100010 int head[N],to[2*N],nextedge[2*N],id[2*N]; int edge[N][2]; int ans[N][2]; int cou; int dp[N][2]; int fa[N]; int faedge[N]; void add(int a,int b,int tempid){ to[cou]=b;nextedge[cou]=head[a];id[cou]=tempid;head[a]=cou++; } void dfs(int u,int tempfa,int tempfaedge){ dp[u][0]=0; dp[u][1]=0; fa[u]=tempfa; faedge[u]=tempfaedge; for(int i=head[u];i!=-1;i=nextedge[i]){ int v=to[i]; if(v==tempfa){ continue; } else if(dp[v][0]!=-1){ if(ans[id[i]][0]!=0){ int tempu=u; while(tempu!=v){ int tempid=faedge[tempu]; ans[tempid][0]=0; ans[tempid][1]=0; tempu=fa[tempu]; //printf("%d %d %dha ",u,v,tempu); } int tempid=id[i]; ans[id[i]][0]=0; ans[id[i]][1]=0; } else{ continue; } } else{ dfs(v,u,id[i]); if(dp[v][0]>dp[u][0]){ dp[u][1]=dp[u][0]; dp[u][0]=dp[v][0]; } else if(dp[v][0]>dp[u][1]){ dp[u][1]=dp[v][0]; } } } return; } int main(){ int t; int n,m; int a,b; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); memset(head,-1,sizeof(head)); memset(ans,-1,sizeof(ans)); memset(dp,-1,sizeof(dp)); cou=0; for(int i=0;i<m;i++){ scanf("%d%d",&a,&b); add(a,b,i); add(b,a,i); edge[i][0]=a; edge[i][1]=b; } dfs(1,-1,-1); for(int i=0;i<m;i++){ if(ans[i][0]){ int u=edge[i][0]; int v=edge[i][1]; if(fa[u]==v){ swap(u,v); } int tempmax=v; tempmax=tempmax>dp[v][0]?tempmax:dp[v][0]; tempmax=tempmax>dp[v][1]?tempmax:dp[v][1]; if(tempmax!=n){ ans[i][0]=tempmax; ans[i][1]=tempmax+1; } else{ int tempu=u; tempmax=0; while(tempu!=-1){ tempmax=tempmax>tempu?tempmax:tempu; tempmax=tempmax>dp[tempu][1]?tempmax:dp[tempu][1]; tempu=fa[tempu]; } ans[i][0]=tempmax; ans[i][1]=tempmax+1; } } } for(int i=0;i<m;i++){ printf("%d %d\n",ans[i][0],ans[i][1]); } } return 0; }