HDU - 6005 Pandaland (无向图最小环,动态加边Dijkstra)

题目链接

题意:求无向图最小环(n<=8000,m<=4000)

动态把边加进去跑Dij,在加入一条边(u,v,c)之前,先求出mindis(u,v),更新答案ans=min(ans,mindis(u,v)+c),复杂度$O(m^2logn)$

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 typedef double db;
 5 const int N=8000+10,inf=0x3f3f3f3f;
 6 int n,m,d[N],hd[N],ne,ka;
 7 struct E {int v,c,nxt;} e[N];
 8 void link(int u,int v,int c) {e[ne]= {v,c,hd[u]},hd[u]=ne++;}
 9 struct P {
10     int x,y;
11     bool operator<(const P& b)const {return x!=b.x?x<b.x:y<b.y;}
12 };
13 map<P,int> p2id;
14 int id(P p) {
15     if(p2id.count(p))return p2id[p];
16     n=p2id.size()+1;
17     return p2id[p]=n;
18 }
19 struct D {
20     int u,g;
21     bool operator<(const D& b)const {return g>b.g;}
22 };
23 priority_queue<D> q;
24 void upd(int u,int g) {if(d[u]>g)d[u]=g,q.push({u,g});}
25 int Dij(int S,int T) {
26     while(q.size())q.pop();
27     for(int i=1; i<=n; ++i)d[i]=inf;
28     upd(S,0);
29     while(q.size()) {
30         int u=q.top().u,g=q.top().g;
31         q.pop();
32         if(g!=d[u])continue;
33         if(u==T)return g;
34         for(int i=hd[u]; ~i; i=e[i].nxt) {
35             int v=e[i].v;
36             upd(v,g+e[i].c);
37         }
38     }
39     return inf;
40 }
41 
42 int main() {
43     int _;
44     for(scanf("%d",&_); _--;) {
45         int ans=inf;
46         n=0;
47         memset(hd,-1,sizeof hd),ne=0;
48         p2id.clear();
49         scanf("%d",&m);
50         while(m--) {
51             int x1,x2,y1,y2,c;
52             scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&c);
53             int u=id({x1,y1}),v=id({x2,y2});
54             ans=min(ans,Dij(u,v)+c);
55             link(u,v,c),link(v,u,c);
56         }
57         printf("Case #%d: %d\n",++ka,ans==inf?0:ans);
58     }
59     return 0;
60 }

 

posted @ 2021-04-04 11:07  jrltx  阅读(99)  评论(0编辑  收藏  举报