zoukankan      html  css  js  c++  java
  • 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
    ");
            else
                printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    wpf 设置 DataGrid中的某一列可以编辑
    wpf GIS 在地图上画正方形和圆形
    C#中treeView内容拖动效果功能的实现
    第三次作业——四则运算
    分布式版本控制系统Git的安装与使用
    第一次作业
    如何让免费的Azure工作起来
    Azure 的初体验
    免费美国手机号码、收发短信工具 – Pinger
    dotnet反编译工具
  • 原文地址:https://www.cnblogs.com/wangfang20/p/3351506.html
Copyright © 2011-2022 走看看