HDU 1599 find the mincost route (无向图的最小环)

 

 

 

题意:

  给一个带权无向图,求其至少有3个点组成的环的最小权之和。

 

思路:

  (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。枚举删除某一条边,求该边两点间的最短距离。要注意的是,重边只留1条权最小的,其他删掉,这样就能保证至少出现3个点。

 

  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代码

 

 

 

  (3)floyd。dijkstra是枚举删某条边,而floyd是枚举相连的两条边。先理解floyd的思想,穷举每个点k作为中间节点来更新其他点a和b之间的距离,而当某个点未被k枚举到时,是不可能有一条路径将其包含在中间的,它顶多可以作为路径的起点或者终点。利用这点,在未枚举到某点k作为中间点时,可以枚举一下与k相连的两条边,即i->k->j。

 

   78ms

 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 int g[N][N], dist[N][N];
 8 
 9 
10 int cal(int n)  //floyd
11 {
12     int ans=INF;
13     for(int k=1; k<=n; k++) //注意枚举顺序。
14     {
15         //枚举两条边i->k->j。
16         for(int i=1; i<=n; i++ )
17         {
18             if(g[i][k]==INF || k==i) continue;
19             for(int j=i+1; j<=n; j++)   //i和j不能相等,才能保证至少3个点。
20             {
21                 if(g[k][j]==INF || dist[i][j]==INF || k==j )    continue;
22                 int dis=g[i][k] + g[k][j] + dist[i][j];
23                 ans=min(ans, dis);
24             }
25         }
26         for(int i=1; i<=n; i++)
27         {
28             for(int j=1; j<=n; j++)
29             {
30                 if(dist[i][k]==INF || dist[k][j]==INF) continue;
31                 dist[i][j]=min(dist[i][j], dist[i][k]+dist[k][j]);
32             }
33         }
34     }
35 
36     return ans==INF? 0: ans;
37 }
38 
39 int main()
40 {
41     freopen("input.txt", "r", stdin);
42     int t, a, b, c, n, m;
43     while(~scanf("%d %d", &n, &m))
44     {
45         memset(g, 0x7f, sizeof(g));
46         for(int i=0; i<m; i++)
47         {
48             scanf("%d%d%d",&a,&b,&c);
49             g[b][a]=g[a][b]=min(g[a][b], c);
50         }
51         memcpy(dist, g, sizeof(g));
52         for(int i=1; i<=n; i++) dist[i][i]=0;
53 
54         int ans=cal(n);
55         if(ans) printf("%d\n", ans);
56         else    printf("It's impossible.\n");
57     }
58     return 0;
59 }
AC代码

 

转载于:https://www.cnblogs.com/xcw0754/p/4695779.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ava实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),可运行高分资源 Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现
C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循语句等)、函数、指针等。下面详细介绍C语言的基本概念和语法。 1. 变量和数据类型 在C语言中,变量用于存储数据,数据类型用于定义变量的类型和范围。C语言支持多种数据类型,包括基本数据类型(如int、float、char等)和复合数据类型(如结构体、联合等)。 2. 运算符 C语言中常用的运算符包括算术运算符(如+、、、/等)、关系运算符(如==、!=、、=、<、<=等)、逻辑运算符(如&&、||、!等)。此外,还有位运算符(如&、|、^等)和指针运算符(如、等)。 3. 控制结构 C语言中常用的控制结构包括if语句、循语句(如for、while等)和switch语句。通过这些控制结构,可以实现程序的分支、循和多路选择等功能。 4. 函数 函数是C语言中用于封装代码的单元,可以实现代码的复用和模块化。C语言中定义函数使用关键字“void”或返回值类型(如int、float等),并通过“{”和“}”括起来的代码块来实现函数的功能。 5. 指针 指针是C语言中用于存储变量地址的变量。通过指针,可以实现对内存的间接访问和修改。C语言中定义指针使用星号()符号,指向数组、字符串和结构体等数据结构时,还需要注意数组名和字符串常量的特殊性质。 6. 数组和字符串 数组是C语言中用于存储同类型数据的结构,可以通过索引访问和修改数组中的元素。字符串是C语言中用于存储文本数据的特殊类型,通常以字符串常量的形式出现,用双引号("...")括起来,末尾自动添加'\0'字符。 7. 结构体和联合 结构体和联合是C语言中用于存储不同类型数据的复合数据类型。结构体由多个成员组成,每个成员可以是不同的数据类型;联合由多个变量组成,它们共用同一块内存空间。通过结构体和联合,可以实现数据的封装和抽象。 8. 文件操作 C语言中通过文件操作函数(如fopen、fclose、fread、fwrite等)实现对文件的读写操作。文件操作函数通常返回文件指针,用于表示打开的文件。通过文件指针,可以进行文件的定位、读写等操作。 总之,C语言是一种功能强大、灵活高效的编程语言,广泛应用于各种领域。掌握C语言的基本语法和数据结构,可以为编程学习和实践打下坚实的基础。
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值