HDU 6005 Pandaland (寻找带权最小环)

Mr. Panda lives in Pandaland. There are many cities in Pandaland. Each city can be treated as a point on a 2D plane. Different cities are located in different locations.
There are also M bidirectional roads connecting those cities. There is no intersection between two distinct roads except their endpoints. Besides, each road has a cost w.
One day, Mr. Panda wants to find a simple cycle with minmal cost in the Pandaland. To clarify, a simple cycle is a path which starts and ends on the same city and visits each road at most once.
The cost of a cycle is the sum of the costs of all the roads it contains.

Input

The first line of the input gives the number of test cases, T. T test cases follow.
Each test case begins with an integer M.
Following M lines discribes roads in Pandaland.
Each line has 5 integers x1,y1,x2,y2,

w, representing there is a road with cost w connecting the cities on (x1,y1) and (x2,y2).

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the cost Mr. Panda wants to know.
If there is no cycles in the map, y is 0.

 找带权最小环

因为有4000条边,所以点的个数最大8000;不能用floyd

所以暴力枚举每一条边跑Dijkstra,题目不存在重边

剪枝优化:如果在Dijkstra中出来的边已经大于当期的ans-w(ij)那么直接跳出

因为只有当d比ans-w(ij)小的时候才会更新答案

注意边的个数...和 0 (因为这挖了好久把边数当成了m)

#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cmath>
#include<map>
#include<cstring>
#include<set>


#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 1e15+10
using namespace std;

const int maxn=40005;

struct edge{
    ll u,v,w,next;
}e[maxn];

ll g[maxn],vis1[maxn],d[maxn];
ll n,m,tot;

struct node{
    ll v,w;
    bool operator < (const node &cmp) const{
        return w>cmp.w;
    }
};

void init()
{

    mem(e,0);
    mem(g,0);
    tot=n=0;
}

void creat_edge(ll u,ll v,ll w)
{
    e[++tot]=(edge){u,v,w,g[u]};
    g[u]=tot;
}

ll dj(ll st,ll ed,ll cheek)
{
    priority_queue<node>q;
    mem(vis1,0);
    for(ll i=1;i<=n;i++)
        d[i]=inf;
    d[st]=0;
    q.push((node){st,0});
    while(!q.empty())
    {
        ll now=q.top().v;
        if(q.top().w>cheek) break;
        q.pop();
        if(vis1[now]) continue;
        vis1[now]=1;
        for(ll i=g[now];i>0;i=e[i].next)
        {
            ll u=e[i].u,v=e[i].v,w=e[i].w;
            if(d[v]>d[u]+w)
            {
                d[v]=d[u]+w;
                q.push((node){v,d[v]});
            }
        }
    }
    return d[ed];
}

int main()
{
    ll t;
    scanf("%lld",&t);
    for(ll k=1;k<=t;k++)
    {
        map<ll,map<ll,ll> >q,vis;
        init();
        scanf("%lld",&m);
        for(ll i=1;i<=m;i++)
        {
            ll x1,x2,y1,y2,w,u,v;
            scanf("%lld%lld%lld%lld%lld",&x1,&y1,&x2,&y2,&w);
            if(!q[x1][y1]) q[x1][y1]=++n;
            if(!q[x2][y2]) q[x2][y2]=++n;
            u=q[x1][y1];
            v=q[x2][y2];
            creat_edge(u,v,w);
            creat_edge(v,u,w);
        }
        ll ans=inf;
        for(int i=1;i<=n;i++)
            for(int j=g[u];j>0;j=e[j].next)
            {
                ll u=e[j].u,v=e[j].v,w=e[j].w;
                if((vis[u][v]<w&&vis[u][v]!=0)||(vis[v][u]<w&&vis[v][u]!=0)) continue;
                vis[u][v]=vis[v][u]=1;
                e[i].w=inf;
                ll temp=dj(u,v,ans-w)+w;
               // cout<<temp<<endl;
                ans=min(ans,temp);
                e[i].w=w;
            }
        if(ans==inf) printf("Case #%lld: 0\n",k);
        else printf("Case #%lld: %lld\n",k,ans);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_40703941/article/details/86574085