1. Question meaning: give you n edges, let you find a ring with the least weight among them
2. Analysis: a ring must start from a point, and finally return to this point. And because every point must be in an edge, we can regard the two ends of an edge as a starting point and an end point. We only need to find the shortest path from the starting point to the end point. The final result plus the weight of this edge is the minimum weight of this ring. We can find all rings by traversing all the edges. Pay attention to add a pruning here: when the sum of the minimum weight is greater than min when the shortest path is found, exit directly.
3. Code:
#include <iostream> #include<bits/stdc++.h> using namespace std; #define INF 0x3f3f3f3f typedef pair<int,int> P; const int maxn = 4000 + 7; int dist[maxn<<1],head[maxn<<1],m,cnt,tot,minn; bool judge[maxn<<1]; struct Edge{ int to,next,val; }edge[maxn<<2]; struct Node{ int from,to,v; }node[maxn]; map<P,int> cp; void addEdge(int a,int b,int c){ edge[tot].to = b;edge[tot].val = c;edge[tot].next = head[a];head[a] = tot++; } void Dijkstra(int a,int b,int v){ memset(judge,0,sizeof(judge)); dist[a] = 0; priority_queue<P,vector<P>,greater<P> > que; que.push(P(0,a)); while(!que.empty()){ P p = que.top(); que.pop(); if(p.first + v > minn)break;//If the current minimum sum + edge weight > global minimum: pruning if(judge[p.second])continue; judge[p.second] = 1; for(int i = head[p.second];~i;i = edge[i].next){ if((p.second==a&&edge[i].to==b)||(p.second==b&&edge[i].to==a))continue; if(!judge[edge[i].to]&&dist[edge[i].to] > p.first + edge[i].val){ dist[edge[i].to] = p.first + edge[i].val; que.push(P(dist[edge[i].to],edge[i].to)); } } } return; } int main() { int T; int t = 0; scanf("%d",&T); while(T--){ t++; cp.clear(); memset(head,-1,sizeof(head)); scanf("%d",&m); cnt = tot = 0; for(int i = 0;i<m;i++){ int x1,y1,x2,y2,c; scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&c); if(!cp[P(x1,y1)])cp[P(x1,y1)] = ++cnt;//Number each point if(!cp[P(x2,y2)])cp[P(x2,y2)] = ++cnt; int s = cp[P(x1,y1)],e = cp[P(x2,y2)];//starting point, end point addEdge(s,e,c); addEdge(e,s,c); node[i].from = s;node[i].to = e;node[i].v = c;//Save each edge } minn = INF; for(int i = 0;i<m;i++){//Loop each edge memset(dist,INF,sizeof(dist)); Dijkstra(node[i].from,node[i].to,node[i].v);//shortest path if(dist[node[i].to]!=INF)minn = min(minn,dist[node[i].to] + node[i].v);//To update } printf("Case #%d: %d\n",t,minn>=INF?0:minn); } return 0; }