我是靠谱客的博主 深情春天,这篇文章主要介绍HDU3760 Ideal Path 逆bfs+贪心,现在分享给大家,希望可以做个参考。

题目链接

题意

  • 最短路径 1–>n;
  • 多条路径情况下选择路径字典序最小的

解题

n–>1 bfs最短路
1–>n 满足最短路的条件下找最小颜色

代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include<iostream> #include<cstdio> #include<algorithm> #include<queue> #include<cstring> #include<vector> #define inf 0x3f3f3f3f using namespace std; int n; int d[100010]; bool vis[100010]; vector<int> g[100010]; struct way{ int u,v,c; way(){ }; way(int a,int b,int c):u(a),v(b),c(c){ }; }; vector<way> ways; vector<int> ans; void bulid(int u,int v,int c){ ways.push_back(way(u,v,c)); g[u].push_back(int(ways.size())-1);//g[u].size():u有几条通路;g[u][i]:u的第i条通路信息存在ways[i]; } void re_bfs(){//从n-1到0 记录最短距离 memset(vis,0,sizeof(vis)); d[n-1]=0; vis[n-1]=1; queue<int> Q; Q.push(n-1); while(!Q.empty()){ int v=Q.front();Q.pop(); for(int i=0;i<g[v].size();i++){ int e=g[v][i]; int w=ways[e].v; if(!vis[w]){ vis[w]=1; d[w]=d[v]+1;//无权图,广搜只访问一次; Q.push(w); } } } } void bfs(){//从0到n-1; // memset(vis,0,sizeof(vis)); ans.clear(); vis[0]=1; // vector<int> NexT; NexT.push_back(0); // for(int i=0;i<d[0];i++){//i小于0到n的距离d ;对于多条最短路径的每一层 int minColor=inf; for(int j=0;j<NexT.size();j++){//NexT.size() int u=NexT[j];//从next中取一个点 for(int k=0;k<g[u].size();k++){//对于每一个与u连同的点 int e=g[u][k];//在ways中的存取位置 int v=ways[e].v;//v点与u点相连 if(d[u]==d[v]+1){//最短路径中的下一个点 minColor=min(minColor,ways[e].c);//更新 } } } //每一层找到它的最小颜色 ans.push_back(minColor); vector<int> Next2;//从颜色最小的点出发,找第下层; for(int j=0;j<NexT.size();j++){//NexT.size() int u=NexT[j];//从next中取一个点 for(int k=0;k<g[u].size();k++){//对于每一个与u连同的点 int e=g[u][k];//在ways中的存取位置 int v=ways[e].v;//v点与u点相连 if(d[u]==d[v]+1 && !vis[v] && ways[e].c==minColor) { vis[v]=1; Next2.push_back(v); } } } NexT=Next2; } printf("%dn",int (ans.size())); for(int i=0;i<ans.size();i++){ if(i)putchar(' '); printf("%d",ans[i]); } printf("n"); } int main(){ int t; scanf("%d",&t); while(t--){ int m; int u,v,c; scanf("%d%d",&n,&m); ways.clear();//qingling fill(g,g+n+1,vector<int>());//g[0]--g[n]=kong vector for(int i=0;i<m;i++){ scanf("%d%d%d",&u,&v,&c); bulid(u-1,v-1,c); bulid(v-1,u-1,c); } re_bfs(); bfs(); } return 0; }

逆向bfs+堆优化的dijkstra

这里写链接内容

逆向bfs+贪心

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include<iostream> #include<cstdio> #include<queue> #include<algorithm> using namespace std; int n,m; struct node{ int u,v,c; node(int u=0,int v=0,int c=0):u(u),v(v),c(c){ }; }e[400005];//两倍m的边 int head[100005]; int Next[400005]; int cnt; void init(){ cnt=0; for(int i=1;i<=n;i++) head[i]=-1; } void add_edge(int u,int v,int c){ e[++cnt]=node(u,v,c);//保存边节点 ,从1开始 Next[cnt]=head[u]; head[u]=cnt; //链表思想存储图的边 //点v的第一个边节点在edge中的位置为cnt=head[v] //下一个点v的边在edge中的位置cnt=next[cnt]; } int d[100005];//distance void bfs(){//无权图的单源最短路径 int q[100005],front=0,rear=0;//模拟队列 for(int i=1;i<=n;i++) d[i]=-1; d[n]=0; q[front]=n; while(front<=rear){ int u=q[front++];//取队列的第一个点 for(int i=head[u];i!=-1;i=Next[i]){//遍历点u的所有边 ; node te=e[i];//取出边节点的信息; if(d[te.v]==-1)//如果边u-->v的v点没有被加入集合,没有被访问 { d[te.v]=d[u]+1;//更新距离 q[++rear]=te.v;//点v入队 } } } } int ans[100005],done[100005]; void bfs2(){ queue<int> q[3]; for(int i=1;i<=n;i++)done[i]=-1; int now=0; int pre=1; q[pre].push(1); int flag=0; while(d[q[pre].front()]>0){//队列中队首顶点到n的距离大于0;//当不满足是时即为取到顶点n时 flag++; int minn=1e9+100;//min_color while(!q[pre].empty()){ int u=q[pre].front();q[pre].pop(); for(int i=head[u];i!=-1;i=Next[i]){ node te=e[i]; if(d[te.v]+1!=d[u]) continue; if(te.c>minn)continue; if(te.c<minn){ while(!q[2].empty())q[2].pop();//找到颜色更小的点,就清空之前入队的顶点 minn=te.c; } q[2].push(te.v);//保存所有=当前min_color的点; } } while(!q[2].empty()){ int u=q[2].front();q[2].pop(); if(done[u]!=flag){ done[u]=flag; q[now].push(u); } } swap(pre,now); ans[flag]=minn; } //write printf("%dn",d[1]); for(int i=1;i<flag;i++){ printf("%d ",ans[i]); } printf("%dn",ans[flag]); } int main(){ int t; cin>>t;//因为忘了读入t,错误查bug好多次,心塞 while(t--){ scanf("%d%d",&n,&m); // init(); // int u,v,c; for(int i=0;i<m;i++){ scanf("%d%d%d",&u,&v,&c); add_edge(u,v,c); add_edge(v,u,c); } //无权单源最短路径 bfs(); // bfs2(); } return 0; }

改天用自己的习惯实现一遍代码,后续+1;

最后

以上就是深情春天最近收集整理的关于HDU3760 Ideal Path 逆bfs+贪心的全部内容,更多相关HDU3760内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(55)

评论列表共有 0 条评论

立即
投稿
返回
顶部