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.
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).
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.
∙1≤T≤50.
∙1≤m≤4000.
∙−10000≤xi,yi≤10000.
∙1≤w≤105.
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
二维平面很多点和边,让你找无向图最小环。
求最小环,只要枚举每条边,把它去掉,求边两头的最短路。
这题数据较多,不妨加一个小剪枝:当迪杰斯特拉的优先队列顶的距离大于当前答案时,直接跳出。
然后就过了。就过了。。。。
补充: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;
}