码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 1599 find the mincost route 最小路(最小环)

时间:2015-08-02 16:23:19      阅读:121      评论:0      收藏:0      [点我收藏+]

标签:

 

 

 

题意:给一个带权无向图,求其最小环的路径权之和。

 

思路:

  (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 }
TLE代码

 

 

  (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 }
AC代码

 

HDU 1599 find the mincost route 最小路(最小环)

标签:

原文地址:http://www.cnblogs.com/xcw0754/p/4695779.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!