Hdu 6005 Pandaland 无向图最小环:最短路剪枝

来源:互联网 发布:软件著作权使用说明书 编辑:程序博客网 时间:2024/06/05 21:54

Pandaland

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


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


1T50.
1m4000.
10000xi,yi10000.
1w105.
 

Sample Input
250 0 0 1 20 0 1 0 20 1 1 1 21 0 1 1 21 0 0 1 591 1 3 1 11 1 1 3 23 1 3 3 21 3 3 3 11 1 2 2 22 2 3 3 33 1 2 2 12 2 1 3 24 1 5 1 4
 

Sample Output
Case #1: 8Case #2: 4
 

Source
2016 CCPC-Final


二维平面很多点和边,让你找无向图最小环。


求最小环,只要枚举每条边,把它去掉,求边两头的最短路。

这题数据较多,不妨加一个小剪枝:当迪杰斯特拉的优先队列顶的距离大于当前答案时,直接跳出。

然后就过了。就过了。。。。


补充:poj 3895 求无向图,边权都为1的最长环

做法:先随便dfs出一棵生成树,dfs的时候,记录每个点在树里的深度,每到一个点扫描所有边,顺便更新答案就可以。


#include <cstdio>#include <iostream>#include <string.h>#include <string> #include <map>#include <queue>#include <deque>#include <vector>#include <set>#include <algorithm>#include <math.h>#include <cmath>#include <stack>#include <iomanip>#define mem0(a) memset(a,0,sizeof(a))#define meminf(a) memset(a,0x3f,sizeof(a))using namespace std;typedef long long ll;typedef long double ld;typedef double db;const int maxn=8005,inf=0x3f3f3f3f;  const ll llinf=0x3f3f3f3f3f3f3f3f;   const ld pi=acos(-1.0L);int head[maxn],dist[maxn];bool visit[maxn];int num,ans;map<pair<int,int>,int> mp; struct Edge {int from,to,dist,pre;};Edge edge[maxn*2];void addedge(int f,int t,int d) {edge[num].from=f;edge[num].to=t;edge[num].dist=d;edge[num].pre=head[f];head[f]=num++;edge[num].from=t;edge[num].to=f;edge[num].dist=d;edge[num].pre=head[t];head[t]=num++;}struct node {int id,dist;node(int id,int dist):id(id),dist(dist) {}bool operator <(const node &x)const {    return dist>x.dist;}};int dj(int n,int s,int t) {int j,i;mem0(visit);priority_queue<node> pq;visit[s]=1;for (j=head[s];j!=-1;j=edge[j].pre) pq.push(node(j,edge[j].dist));meminf(dist);dist[s]=0;for (int k=1;k<n;k++) {if (pq.top().dist>ans) break;i=pq.top().id;int to=edge[i].to;if (visit[to]) continue;visit[to]=1;dist[to]=pq.top().dist;pq.pop();for (j=head[to];j!=-1;j=edge[j].pre) if (!visit[edge[j].to]&&dist[to]+edge[j].dist<ans) pq.push(node(j,dist[to]+edge[j].dist));}return dist[t];}int main() {int cas,cnt=0;scanf("%d",&cas);while (cas--) {cnt++;int n,i,j,x,y,s,t,d,m=0;mp.clear();num=0;memset(head,-1,sizeof(head));scanf("%d",&n);ans=inf;for (i=1;i<=n;i++) {scanf("%d%d",&x,&y);s=mp[make_pair(x,y)];if (!s) s=mp[make_pair(x,y)]=++m;scanf("%d%d%d",&x,&y,&d);t=mp[make_pair(x,y)];if (!t) t=mp[make_pair(x,y)]=++m;addedge(s,t,d);}for (i=0;i<n;i++) {d=edge[i*2].dist;edge[i*2].dist=edge[i*2+1].dist=inf;int x=dj(m,edge[i*2].from,edge[i*2].to);ans=min(ans,x+d);edge[i*2].dist=edge[i*2+1].dist=d;}if (ans==inf) ans=0;printf("Case #%d: %d\n",cnt,ans);}return 0;}



原创粉丝点击