G - Pandaland HDU - 6005 (找最小环)

题目链接:https://cn.vjudge.net/contest/275153#problem/G

具体思路: 我们可以按照暴力的方法进行做 , 我们可以枚举每一条边,将这条边的权值设置为inf,然后再去跑最短路,起点是这条边的起点,如果说这条边的另一个点能够到达,并且总的路径花费小于inf,这就证明了有回路,然后再去从这些回路里面去找最小花费就可以了

AC代码:

#include<bits/stdc++.h>
using namespace std;
# define ll long long
const int maxn = 10000+100;
# define inf 0x3f3f3f3f
const int mod = 1e9;
map<pair<int,int>,int>vis;
int head[maxn],num,dis[maxn];
int ans;
struct node
{
    int fr;
    int to;
    int cost;
    int nex;
} edge[maxn];
struct point
{
    int v;
    int cost;
    point() {}
    point(int xx,int yy)
    {
        v=xx;
        cost=yy;
    }
    friend bool operator < (point a,point b)
    {
        return a.cost>b.cost;
    }
};
void init()
{
    vis.clear();
    num=0;
    memset(head,-1,sizeof(head));
    ans=inf;
}
void addedge(int fr,int to,int cost)
{
    edge[num].to=to;
    edge[num].fr=fr;
    edge[num].nex=head[fr];
    edge[num].cost=cost;
    head[fr]=num++;
}
void krustra(int fr,int cost)
{
    memset(dis,inf,sizeof(dis));
    priority_queue<point>q;
    dis[fr]=0;
    q.push(point(fr,0));
    while(!q.empty())
    {
        point tmp=q.top();
        q.pop();
        if(tmp.cost>ans)continue;
        if(dis[tmp.v]+cost>ans)break;
        for(int i=head[tmp.v]; i!=-1; i=edge[i].nex)
        {
            int u=edge[i].to;
            if(dis[u]>dis[tmp.v]+edge[i].cost)
            {
                dis[u]=dis[tmp.v]+edge[i].cost;
                q.push(point(u,dis[u]));
            }
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    int Case=0;
    while(T--)
    {
        int n;
        init();
        scanf("%d",&n);
        int x1,y1,x2,y2,d;
        int dfn=0;
        for(int i=1; i<=n; i++)
        {
            scanf("%d %d %d %d %d",&x1,&y1,&x2,&y2,&d);
            if(vis[make_pair(x1,y1)]==0)
            {
                vis[make_pair(x1,y1)]=++dfn;
            }
            if(vis[make_pair(x2,y2)]==0)
            {
                vis[make_pair(x2,y2)]=++dfn;
            }
            addedge(vis[make_pair(x2,y2)],vis[make_pair(x1,y1)],d);
            addedge(vis[make_pair(x1,y1)],vis[make_pair(x2,y2)],d);
        }
        for(int i=0; i<num; i+=2)
        {
            int tmp=edge[i].cost;
            edge[i].cost=inf;
            edge[i+1].cost=inf;//注意这是双向边,所以需要将相邻的两条边的权值都设置为inf
            krustra(edge[i].fr,tmp);
            ans=min(ans,dis[edge[i].to]+tmp);
            edge[i].cost=tmp;
            edge[i+1].cost=tmp;
        }
        printf("Case #%d: ",++Case);
        if(ans==inf)printf("%d\n",0);
        else printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2018-12-14 17:16  Let_Life_Stop  阅读(302)  评论(0编辑  收藏  举报