HDU - 6005 Pandaland (dijkstra)

原题:

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, x1,y1,x2,y2, w, representing there is a road with cost w connecting the cities on  (x1,y1) (x1,y1) and  (x2,y2). (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. 

limits


1T50. ∙1≤T≤50. 
1m4000. ∙1≤m≤4000. 
10000xi,yi10000. ∙−10000≤xi,yi≤10000. 
1w105. ∙1≤w≤105. 
Sample Input
2
5
0 0 0 1 2
0 0 1 0 2
0 1 1 1 2
1 0 1 1 2
1 0 0 1 5
9
1 1 3 1 1
1 1 1 3 2
3 1 3 3 2
1 3 3 3 1
1 1 2 2 2
2 2 3 3 3
3 1 2 2 1
2 2 1 3 2
4 1 5 1 4
Sample Output
Case #1: 8
Case #2: 4

题意:

      求无向图中的权值最小环。


思路:

      枚举所有边,将其权值设为INF,求该路径两节点的最短路加其权值,找最小。注意剪枝。


#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <deque>
#include <string>
#include <cmath>
#include <vector>
#include <utility>
#include <set>
#include <map>
#include <sstream>
#include <climits>
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#define pi acos(-1.0)
#define INF 2147483647
using namespace std;
typedef long long ll;
typedef pair <int,int > P;
map<P,int> m;
struct edge
{
    int from,to,cost;
};
typedef pair<int,int > P;
vector<int> G[4005];//节点存储ed中路径的编号
vector<edge> ed;
ll d[4005],res;
void dijkstra(int s,int dis)
{
    priority_queue<P,vector<P>,greater<P> > que;
    fill(d,d+4005,INF);
    d[s]=0;
    que.push(P(0,s));
    while(!que.empty())
    {
        P p=que.top();
        que.pop();
        int v=p.second;
        if(d[v]+dis>=res)//剪枝,当已经大于res时跳出
            break;
        if(d[v]<p.first)
            continue;
        for(int i=0; i<G[v].size(); i++)
        {
            int u=G[v][i];
            edge e=ed[u];
            if(d[e.to]>d[v]+e.cost)
            {
                d[e.to]=d[v]+e.cost;
                que.push(P(d[e.to],e.to));
            }
        }
    }
}
int main ()
{
    int T;
    scanf("%d",&T);
    for(int kase=1; kase<=T; kase++)
    {
        for(int i=0; i<4005; i++)
            G[i].clear();
        ed.clear();
        m.clear();
        int num;
        int cnt=0;
        scanf("%d",&num);
        for(int i=0; i<num; i++)
        {
            int a,b,c,d,cost;
            scanf("%d%d%d%d%d",&a,&b,&c,&d,&cost);
            if(m[P(a,b)]==0)
                m[P(a,b)]=++cnt;
            if(m[P(c,d)]==0)
                m[P(c,d)]=++cnt;
            edge e;
            e.cost=cost;
            e.from=m[P(a,b)];
            e.to=m[P(c,d)];
            ed.push_back(e);
            int q=ed.size();
            G[m[P(a,b)]].push_back(q-1);
            e.from=m[P(c,d)];
            e.to=m[P(a,b)];
            ed.push_back(e);
            G[m[P(c,d)]].push_back(q);
        }
        res=INF;
        for(int i=0; i<ed.size(); i+=2)
        {
            edge &e=ed[i];
            int dist=e.cost;
            e.cost=INF;
            ed[i+1].cost=INF;
            dijkstra(e.from,dist);
            res=min(res,d[e.to]+dist);
            e.cost=dist;
            ed[i+1].cost=dist;
        }
        if(res>=INF)
            res=0;
        printf("Case #%d: %lld\n",kase,res);
    }
    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值