对于这道题,一开始看了题解,信誓旦旦的觉得我能写,结果发现超时,虽然继续找题解,但是心里仍然吐槽,怎么会超时?看了别人写的以后,才发现有更巧妙的办法,不用对于每条边都进行一个搜索,以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;
}