标签:
题意:给一个带权无向图,求其最小环的路径权之和。
思路:
(1)DFS可以做,实现了确实可以,只是TLE了。量少的时候应该还是可以水一下的。主要思路就是,深搜过程如果当前点搜到一个点访问过了,而其不是当前点的父亲,则肯定有环,可以更新答案。深搜过程要记录路径和,父亲,是否访问过等等信息,因为图可能有多个连通分量。
1 #include <bits/stdc++.h> 2 #define INF 0x7f7f7f7f 3 #define pii pair<int,int> 4 #define LL unsigned long long 5 using namespace std; 6 const int N=110; 7 struct node 8 { 9 int from, to, cost; 10 node(){}; 11 node(int from,int to,int cost):from(from),to(to),cost(cost){}; 12 }edge[N*N]; 13 int edge_cnt; 14 vector<int> vect[N]; 15 16 void add_node(int from,int to,int cost) 17 { 18 edge[edge_cnt]=node(from, to, cost); 19 vect[from].push_back(edge_cnt++); 20 } 21 22 int sum[N], vis[N], inq[N], pre[N], ans; 23 24 void DFS(int x) 25 { 26 vis[x]=1; 27 inq[x]=1; 28 for(int i=0; i<vect[x].size(); i++) 29 { 30 node e=edge[vect[x][i]]; 31 if( inq[e.to] && pre[x]!=e.to ) 32 { 33 ans=min(ans, sum[x]+e.cost-sum[e.to]); 34 } 35 if( !inq[e.to] ) 36 { 37 pre[e.to]=x; 38 sum[e.to]=sum[x]+e.cost; 39 DFS(e.to); 40 sum[e.to]=0; 41 pre[e.to]=0; 42 } 43 } 44 inq[x]=0; 45 } 46 47 int cal(int n) 48 { 49 ans=INF; 50 memset(vis,0,sizeof(vis)); 51 memset(inq,0,sizeof(inq)); 52 memset(pre,0,sizeof(pre)); 53 memset(sum,0,sizeof(sum)); 54 for(int i=1; i<=n; i++) 55 { 56 if(!vis[i]) 57 DFS(i); 58 } 59 return ans==INF? 0: ans; 60 } 61 62 int main() 63 { 64 freopen("input.txt", "r", stdin); 65 int t, a, b, c, n, m; 66 while(~scanf("%d %d", &n, &m)) 67 { 68 edge_cnt=0; 69 for(int i=0; i<=n; i++) vect[i].clear(); 70 71 for(int i=0; i<m; i++) 72 { 73 scanf("%d%d%d",&a,&b,&c); 74 add_node(a, b, c); 75 add_node(b, a, c); 76 } 77 78 int ans=cal(n); 79 if(ans) printf("%d\n", ans); 80 else printf("It‘s impossible.\n"); 81 } 82 return 0; 83 }
(2)dijkstra。穷举每条边,删除它后,求该边两点间的最短距离。要注意的是,有重边的存在,应该只保留权值最小的一条边即可。
608ms
1 #include <bits/stdc++.h> 2 #include <iostream> 3 #include <cstdio> 4 #include <vector> 5 #include <cstring> 6 #include <deque> 7 #define INF 0x7f7f7f7f 8 #define pii pair<int,int> 9 #define LL unsigned long long 10 using namespace std; 11 const int N=110; 12 struct node 13 { 14 int from, to, cost, tag; 15 node(){}; 16 node(int from,int to,int cost):from(from),to(to),cost(cost),tag(1){}; 17 }edge[N*N]; 18 int edge_cnt; 19 vector<int> vect[N]; 20 int g[N][N]; 21 void add_node(int from,int to,int cost) 22 { 23 edge[edge_cnt]=node(from, to, cost); 24 vect[from].push_back(edge_cnt++); 25 } 26 27 28 int vis[N], cost[N]; 29 int dijkstra(int s,int e) 30 { 31 memset(cost, 0x7f, sizeof(cost)); 32 memset(vis, 0, sizeof(vis)); 33 cost[s]=0; 34 priority_queue<pii,vector<pii>,greater<pii> > que; 35 que.push(make_pair(0, s)); 36 37 while(!que.empty()) 38 { 39 int x=que.top().second; 40 que.pop(); 41 if(vis[x]) continue; 42 vis[x]=1; 43 for(int i=0; i<vect[x].size(); i++) 44 { 45 node e=edge[vect[x][i]]; 46 if( e.tag && cost[e.to]>cost[x]+e.cost ) 47 { 48 cost[e.to]=cost[x]+e.cost; 49 que.push(make_pair(cost[e.to], e.to)); 50 } 51 } 52 } 53 return cost[e]; 54 55 } 56 57 int cal() 58 { 59 int ans=INF; 60 for(int i=0; i<edge_cnt; i+=2) 61 { 62 edge[i].tag=0; 63 edge[i^1].tag=0; 64 ans=min(ans, edge[i].cost+dijkstra(edge[i].from, edge[i].to)); 65 edge[i].tag=1; 66 edge[i^1].tag=1; 67 } 68 return ans==INF? 0: ans; 69 } 70 71 int main() 72 { 73 freopen("input.txt", "r", stdin); 74 int t, a, b, c, n, m; 75 while(~scanf("%d %d", &n, &m)) 76 { 77 edge_cnt=0; 78 for(int i=0; i<=n; i++) vect[i].clear(); 79 memset(g, 0x7f, sizeof(g)); 80 81 for(int i=0; i<m; i++) 82 { 83 scanf("%d%d%d",&a,&b,&c); 84 g[b][a]=g[a][b]=min(g[a][b], c); 85 } 86 for(int i=1; i<=n; i++) //为了去重边 87 { 88 for(int j=i+1; j<=n; j++) 89 { 90 if(g[i][j]<INF) 91 { 92 add_node(i, j, g[i][j]); 93 add_node(j, i, g[i][j]); 94 } 95 } 96 } 97 int ans=cal(); 98 if(ans) printf("%d\n", ans); 99 else printf("It‘s impossible.\n"); 100 } 101 return 0; 102 }
HDU 1599 find the mincost route 最小路(最小环)
标签:
原文地址:http://www.cnblogs.com/xcw0754/p/4695779.html