uva 12544 无向图最小环

思路:这题的N有500,直接floyd肯定超时。

我的做法是每次枚举一个点,求出包含这个点的最小环。

对所有最小环取最小值。求包含某个点的最小环我用的是启发式搜索,先以该点求一次spfa,然后dfs解决问题。

#include<iostream>

#include<cstdio>

#include<cstring>

#include<algorithm>

#define Maxn 600

#define inf 1000000

using namespace std;

int head[Maxn],vi[Maxn],dis[Maxn],e,que[Maxn*100],ans,dist[Maxn];

struct Edge{

    int u,v,next;

}edge[Maxn*100];

void init()

{

    memset(head,-1,sizeof(head));

    memset(vi,0,sizeof(vi));

    e=0;

}

void add(int u,int v)

{

    edge[e].u=u,edge[e].v=v,edge[e].next=head[u],head[u]=e++;

    edge[e].u=v,edge[e].v=u,edge[e].next=head[v],head[v]=e++;

}



void spfa(int u)

{

    int i,j,v,now,rear,he;

    for(i=0;i<Maxn;i++){

        dist[i]=inf;

        vi[i]=0;

    }

    dist[u]=0;

    he=rear=0;

    que[he++]=u;

    while(he!=rear){

        now=que[rear++];

        vi[now]=0;

        for(i=head[now];i!=-1;i=edge[i].next){

            v=edge[i].v;

            if(v==now) continue;

            if(dist[now]+1<dist[v]){

                dist[v]=dist[now]+1;

                if(!vi[v]){

                    que[he++]=v;

                    vi[v]=1;

                }

            }

        }

    }

    return ;

}

void dfs(int u,int pre)

{

    int i,v;

    for(i=head[u];i!=-1;i=edge[i].next){

        v=edge[i].v;

        if(v==pre) continue;

        if(dis[v]==0){

            ans=min(ans,dis[u]+1);

            continue;

        }

        if(dis[u]+dist[u]>=ans)

            return ;

        if(dis[u]+1<dis[v]){

            dis[v]=dis[u]+1;

            dfs(v,u);

        }

    }

}

int main()

{

    int n,m,i,j,u,v,t,Ca=0;

    scanf("%d",&t);

    while(t--){

        init();

        scanf("%d%d",&n,&m);

        for(i=1;i<=m;i++){

            scanf("%d%d",&u,&v);

            u++,v++;

            add(u,v);

        }

        ans=inf;

        for(i=1;i<=n;i++){

            for(j=0;j<=n;j++)

                dis[j]=inf;

            dis[i]=0;

            spfa(i);

            dfs(i,0);

        }

        printf("Case %d: ",++Ca);

        if(ans>=inf)

            printf("impossible\n");

        else

            printf("%d\n",ans);

    }

    return 0;

}

 

你可能感兴趣的:(uva)