dijkstra求最小环

任意一个环的权值,我们都可以看成两个有边相连的结点i、j的直接距离加上i、j间不包含边(边i->j)的最短路径。

求最短路径我们第一个想到的就是Dijkstra算法。

而Dijkstra所求的是一个点到所有点的最短距离。

用Dijkstra所求的i、j的最短距离一定是i、j的直接距离(如果i,j连通),所以我们需要先将i、j的边从图中删除(若i,j不连通,则不用删除),再用Dijkstra求新图中i、j的最短距离即可。

所以我们每次在图中选取一条边,把它从图中删掉.

然后对删掉的那条边所对应的2点进行Dijkstra,也就是m次Dijkstra。

时间复杂度:若为稀疏图,复杂度为O(n^3)

                    若为稠密图,复杂度为O(n^4)

 

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<string>
 6 #include<queue>
 7 #include<cmath>
 8 #define ll long long
 9 #define DB double
10 #define mod 1000000007
11 #define eps 1e-3
12 #define inf 2147483600
13 using namespace std;
14 inline int read()
15 {
16     int x=0,w=1;char ch=getchar();
17     while(ch<'0' || ch>'9'){if(ch=='-') w=-1;ch=getchar();}
18     while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
19     return x*w;
20 }
21 const int N=1e3+90;
22 struct node{
23     int u,v,c,ne;
24 }e[N];
25 int h[N],tot,n,m,x,y;
26 void add(int u,int v,int c)
27 {
28     tot++;e[tot]=(node){u,v,c,h[u]};h[u]=tot;
29 }
30 struct kk{
31     int id,dis;
32     bool operator<(const kk &x)const{
33       return dis>x.dis;
34     }
35 };
36 int d[N],v[N],ans;
37 priority_queue<kk>q;
38 void dijkstra(int s)
39 {
40     for(int i=1;i<=n;++i) d[i]=inf,v[i]=0;
41     d[s]=0;q.push((kk){s,0});
42     while(!q.empty())
43     {
44         int ff=q.top().id,dis=q.top().dis;q.pop();
45         if(v[ff]) continue;
46         v[ff]=1;
47         for(int i=h[ff];i;i=e[i].ne)
48         {
49             int rr=e[i].v;
50             if(ff==x && rr==y) continue;
51             if(ff==y && rr==x) continue;
52             d[rr]=dis+e[i].c;
53             q.push((kk){rr,d[rr]});
54         }
55     }
56 }
57 int main()
58 {
59     while(scanf("%d%d",&n,&m)!=EOF)
60     {
61          tot=0;ans=inf;
62          memset(h,0,sizeof(h));
63          for(int i=1;i<=m;++i)
64          {
65             int x,y,c;x=read();y=read();c=read();
66             add(x,y,c);add(y,x,c);
67          }
68           for(int i=1;i<=tot;i+=2)
69           {
70              x=e[i].u;y=e[i].v;
71              dijkstra(x);
72              ans=min(ans,d[y]+e[i].c);
73           }
74           if(ans==inf) cout<<"It's impossible."<<endl;
75           else cout<<ans<<endl; 
76     }
77     return 0;
78 }
View Code

大部分情况下还是不用这个的,因为会T很惨。

喵喵~~

 

posted @ 2018-03-01 18:53  月亮茶  阅读(955)  评论(0编辑  收藏  举报