1. 程式人生 > >[dijkstra] 帶權邊 查詢權值最小的環 HDU6005

[dijkstra] 帶權邊 查詢權值最小的環 HDU6005

Pandaland

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1387    Accepted Submission(s): 353


 

Problem Description

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.

limits


∙1≤T≤50.
∙1≤m≤4000.
∙−10000≤xi,yi≤10000.
∙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

 

 

Source

2016 CCPC-Final

 

 

列舉每條邊
從該邊起點向終點跑最短路, 加上這條邊的權值, 即為環的權值

#include <bits/stdc++.h>
using namespace std;
const int mm = 4010, mn = 8020;
const int inf = 0x3f3f3f3f;

int cnt;
typedef pair<int, int> P;

int sum;
int to[2 * mm], nx[2 * mm], cost[2 * mm], fr[mn];
void addedge(int a, int b, int c)
{
	to[sum] = b;
	nx[sum] = fr[a];
	cost[sum] = c;
	fr[a] = sum++;
	
	to[sum] = a;
	nx[sum] = fr[b];
	cost[sum] = c;
	fr[b] = sum++;
}
bool vis[mn];
int dis[mn];
struct node 
{
	int id, dist;
};
bool operator <(const node& a, const node& b)
{
	return a.dist > b.dist;
}

int ans = inf;
void dijkstra(int s, int t)
{
	memset(vis, 0, sizeof vis);
	for (int i = 0; i < cnt; i++)
		dis[i] = inf;
		
	dis[s] = 0;
	priority_queue<node> q;
	node no;
	no.id = s, no.dist = 0;
	q.push(no);
	
	while (!q.empty())
	{
		node p = q.top();
		q.pop();
		
		if (p.dist > ans) // 無法更新答案 剪枝
			break;
		
		if (vis[p.id])
			continue;
		vis[p.id] = 1;
		
		for (int i = fr[p.id]; i != -1; i = nx[i])
		{
			/// 是選中的邊, 跳過
			if ((p.id == s && to[i] == t) || (p.id == t && to[i] == s))
				continue;
			if (!vis[to[i]] && dis[to[i]] > dis[p.id] + cost[i])
			{
				dis[to[i]] = dis[p.id] + cost[i];
				node nn;
				nn.id = to[i], nn.dist = dis[to[i]];
				q.push(nn);
			}
		}
	}
}

map<pair<int, int>, int> mp;
int a[mm], b[mm], c[mm], d[mm], e[mm];
int main()
{
	int T;
	scanf("%d", &T);
	for (int cas = 1; cas <= T; cas++)
	{
		ans = inf;
		cnt = 0;
		sum = 0;
		mp.clear();
		memset(fr, -1, sizeof fr);
		
		int m;
		scanf("%d", &m);
		for (int i = 1; i <= m; i++)
		{
			scanf("%d %d %d %d %d", &a[i], &b[i], &c[i], &d[i], &e[i]);
			if (mp.count(P(a[i], b[i])) == 0)
				mp[P(a[i], b[i])] = cnt++;
			if (mp.count(P(c[i], d[i])) == 0)
				mp[P(c[i], d[i])] = cnt++;
			addedge(mp[P(a[i], b[i])], mp[P(c[i], d[i])], e[i]);
		}
		
		for (int i = 1; i <= m; i++)
		{
			int s = mp[P(a[i], b[i])];
			int t = mp[P(c[i], d[i])];
			
			dijkstra(s, t);
			ans = min(ans, dis[t] + e[i]);
		}
		if (ans == inf)
			printf("Case #%d: 0\n", cas);
		else 
			printf("Case #%d: %d\n", cas, ans);
	}
	return 0;
}