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;
}


posted @ 2015-08-24 20:46  buzhidaohahaha  阅读(139)  评论(0编辑  收藏  举报