GYM
来源:互联网 发布:36o安全卫士mac 编辑:程序博客网 时间:2024/05/21 09:48
题意:给你一张无向图,点分为0,1两种,求最近的两个1的距离,和他们的坐标。
解题思路:SPFA算法的思想很好的被应用了!做完这题对SPFA理解更加深刻了!思路是,先求出所有点,到他最近的1的距离。然后枚举所有的边,判断这条边的两边是什么类型的节点,分为三种情况讨论。如果都是1,直接更新答案。如果都是0,那么看看这两个0最近的1是不是同一个1,不是的话更新答案,一个0一个1的话,判断那个0最近的1是不是这个1,不是的话更新答案!所以这里的难点是怎么求所有点离他最近的1的距离……直接用SPFA松弛即可!
#include <iostream>#include <queue>#include <memory.h>using namespace std;typedef long long int ll;struct edge{ int v1; int v2; ll w; int next;} e[1000005];int edge_num = 0;int head[1000005];void insert_edge(int v1, int v2, ll w){ e[edge_num].v1 = v1; e[edge_num].v2 = v2; e[edge_num].w = w; e[edge_num].next = head[v1]; head[v1] = edge_num++;}int N, M;ll d[1000005];int type[1000005];int near[1000005];bool vis[1000005];void spfa(){ queue<int> que; for (int i = 1; i <= N; i++) if (!d[i]) { que.push(i); vis[i] = 1; } while (!que.empty()) { int tp = que.front(); que.pop(); vis[tp] = 0; for (int i = head[tp]; i!=-1; i = e[i].next) { int v2 = e[i].v2; if (d[tp] + e[i].w < d[v2]) { d[v2] = d[tp] + e[i].w; near[v2] = near[tp]; if (!vis[v2]) { vis[v2] = 1; que.push(v2); } } } }}int main(){ scanf("%d%d", &N, &M); for (int i = 1; i <= N; i++) { scanf("%d", &type[i]); if (type[i]) { d[i] = 0; near[i] = i; } else d[i] = 0x3f3f3f3f3f3f3f3f; } edge_num = 0; memset(head, -1, sizeof(head)); int v1, v2; ll w; for (int i = 0; i < M; i++) { scanf("%d%d%lld", &v1, &v2, &w); insert_edge(v1, v2, w); insert_edge(v2, v1, w); } spfa();// for(int i=1;i<=N;i++)// cout<<near[i]<<endl; ll ans = 0x3f3f3f3f3f3f3f3f; for (int i = 0; i < edge_num; i++) { if (type[e[i].v1] == 1 && type[e[i].v2] == 1) { if (e[i].w < ans) { ans = e[i].w; v1 = e[i].v1; v2 = e[i].v2; } } if (type[e[i].v1] == 0 && type[e[i].v2] == 1) { if (near[e[i].v1] != e[i].v2) if (e[i].w + d[e[i].v1] < ans) { ans = e[i].w + d[e[i].v1]; v1 = near[e[i].v1]; v2 = e[i].v2; } } if (type[e[i].v1] == 1 && type[e[i].v2] == 0) { if (near[e[i].v2] != e[i].v1) if (e[i].w + d[e[i].v2] < ans) { ans = e[i].w + d[e[i].v2]; v1 = e[i].v1; v2 = near[e[i].v2]; } } if (type[e[i].v1] == 0 && type[e[i].v2] == 0) { if (near[e[i].v2] != near[e[i].v1]) if (e[i].w + d[e[i].v1] + d[e[i].v2] < ans) { ans = e[i].w + d[e[i].v1] + d[e[i].v2]; v1 = near[e[i].v1]; v2 = near[e[i].v2]; } } } if (ans == 0x3f3f3f3f3f3f3f3f) { printf("No luck at all\n"); } else { printf("%lld\n%d %d\n", ans, v1, v2); } return 0;}
阅读全文
0 0
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- 1103木棒还原(重写)
- 接口
- Java四种线程池和工作队列
- MyBatis Generator系列(八)----MyBatis Generator自定义插件实现自定义Mapper
- 微信PK阿里出新功能,小马哥躺着赚钱!
- GYM
- 第11章 开发板做中继功能
- Java基础知识学习之路-07-第五章-面向对象(下)
- Python通过循环压缩字符串 例如aaabbbbaaccdde>>>a5b4c2d2e1
- header 之 Content-type 应用
- pyhton学习之ModuleNotFoundError: No module named 'win32api'错误
- 魅族手机连不上adb的解决方法
- 【opencv学习之十八】基本绘图工具line circle rectangle ellipse等
- PhotoShop CC 2017软件工具面板使用---吸管工具