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 }

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

喵喵~~

原文地址:https://www.cnblogs.com/adelalove/p/8488185.html

时间: 2024-11-05 11:47:28

dijkstra求最小环的相关文章

Floyd求最小环

首先求最小环有一个比较好想的方法:每次删掉一条边,看看这条边n所连的点i之间的距离(dijkstra),时间复杂度O(m*V^2*logv) 其实floyd也能完成这个功能.f[i][j][k]表示i到j在中间点为1~k的最近距离 对于一个环,我们假设i和j中只夹这一个数k,则环长为f[i][j][k-1]+map[i][k]+map[k][j],枚举一下 #include<iostream> #include<cstdio> #include<algorithm> #

HDU - 1599 find the mincost route(Floyd求最小环)

find the mincost route Time Limit: 2000MS Memory Limit: 32768KB 64bit IO Format: %I64d & %I64u Submit Status Description 杭州有N个景区,景区之间有一些双向的路来连接,现在8600想找一条旅游路线,这个路线从A点出发并且最后回到A点,假设经过的路线为V1,V2,....VK,V1,那么必须满足K>2,就是说至除了出发点以外至少要经过2个其他不同的景区,而且不能重复经过同一个

【BZOJ 1027】 (凸包+floyd求最小环)

[题意] 某公司加工一种由铁.铝.锡组成的合金.他们的工作很简单.首先进口一些铁铝锡合金原材料,不同种类的原材料中铁铝锡的比重不同.然后,将每种原材料取出一定量,经过融解.混合,得到新的合金.新的合金的铁铝锡比重为用户所需要的比重. 现在,用户给出了n种他们需要的合金,以及每种合金中铁铝锡的比重.公司希望能够订购最少种类的原材料,并且使用这些原材料可以加工出用户需要的所有种类的合金. [分析] 只要考虑前两个物质的比例,因为加起来等于1. 如果你看过zoj3154,就会知道这题的模型,用二元组表

hdu 1599 find the mincost route(flyod求最小环)

Problem Description 杭州有N个景区,景区之间有一些双向的路来连接,现在8600想找一条旅游路线,这个路线从A点出发并且最后回到A点,假设经过的路线为V1,V2,....VK,V1,那么必须满足K>2,就是说至除了出发点以外至少要经过2个其他不同的景区,而且不能重复经过同一个景区.现在8600需要你帮他找一条这样的路线,并且花费越少越好. Input 第一行是2个整数N和M(N <= 100, M <= 1000),代表景区的个数和道路的条数. 接下来的M行里,每行包括

多源最短路径Floyd、Floyd求最小环【模板】

Floyd算法:用来找出每对点之间的最短距离.图可以是无向图,也可以是有向图,边权可为正,也可以为负,唯一要求是不能有负环. 1.初始化:将Map[][]中的数据复制到Dist[][]中作为每对顶点之间的最短路径的初值,Pre[i][j] = i 表示 i 到 j 路径中 j 的前一节点. 2. k 从 1 到 N 循环 N 次,每次循环中,枚举图中不同的两点 i,j,如果Dist[i][j] > Dist[i][k] + Dist[k][j],则更新Dist[i][j] = Dist[i][k

Dijkstra求含权图最短通路;试探与回溯保证枚举的不遗漏不重复;国际象棋八皇后问题

求两节点的最短通路,对于无权图,可以通过图的广度优先遍历求解.含权图一般通过Dijkstra算法求解. import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; public class Shortest { static class Cell{ int node;//连接到哪个节点 int weight

eoj1818 dijkstra求最短路及其条数

求出有n(1 < n <= 100)个结点有向图中,结点1到结点n的最短路径,以及最短路径的条数. Input 第一行有2个整数n和m( 0 < m < 3000),接下来m行每行有三个整数u,v,w结点u到v之间有一条权为w的边(w<100000). Output 输出只有一行,为结点1到结点n之间的最短路径及其条数(用空格隔开),如果1到n之间不存在路径,输出 -1 0. Sample Input 3 3 1 2 10 2 3 15 1 3 25 Sample Outpu

Floyd求最小环!(转载,非原创)

//Floyd 的 改进写法可以解决最小环问题,时间复杂度依然是 O(n^3),储存结构也是邻接矩阵 int mincircle = infinity; Dist = Graph; for(int k=0;k<nVertex;++k){ //新增部分: for(int i=0;i<k;++i) for(int j=0;j<i;++j) mincircle = min(mincircle,Dist[i][j]+Graph[j][k]+Graph[k][i]); //通常的 floyd 部分

BZOJ_1027_[JSOI2007]_合金_(计算几何+Floyd求最小环)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1027 共三种金属,\(m\)种材料,给出每种材料中三种金属的占比. 给出\(n\)种合金的三种金属占比.用材料做合金,问最少需要多少种材料. 分析 首先,由于三种金属的占比相加为1,所以确定了前两项,最后一项也就确定了,我们可以用二唯坐标\((x,y)\)表示前两项,这样每种材料和合金就是二维平面上的一个点. 接下来是用材料做合金. 首先来考虑用两种材料做合金,两种材料为\((x1,y1)和