奇怪的连通图_1545
来源:互联网 发布:软件学报 ei 编辑:程序博客网 时间:2024/05/23 02:17
- 题目描述:
已知一个无向带权图,求最小整数k。使仅使用权值小于等于k的边,节点1可以与节点n连通。
- 输入:
输入包含多组测试用例,每组测试用例的开头为一个整数n(1 <= n <= 10000),m(1 <= m <= 100000),代表该带权图的顶点个数,和边的个数。
接下去m行,描述图上边的信息,包括三个整数,a(1 <= a <= n),b(1 <= b <= n),c(1 <= c <= 1000000),表示连接顶点a和顶点b的无向边,其权值为c。
- 输出:
输出为一个整数k,若找不到一个整数满足条件,则输出-1。
- 样例输入:
3 31 3 51 2 32 3 23 21 2 32 3 53 11 2 3
- 样例输出:
35-1
二分查找 复杂度较高,其实考察的是并查集
#include <iostream>#include <vector>#include <algorithm>#include <cstdio>using namespace std; struct edge_t { int a, b; int dist;}; int n, m;vector<edge_t> edges;vector<int> father; int findFather(int x) { while (x != father[x]) { x = father[x]; } return x;} bool cmp(const edge_t &a, const edge_t &b) { return a.dist < b.dist;} void init() { for (int i = 0; i < father.size(); ++i) father[i] = i; sort(edges.begin(), edges.end(), cmp);} void solve() { for (int i = 0; i < m; ++i) { int fa = findFather(edges[i].a); int fb = findFather(edges[i].b); if (fa < fb) father[fb] = fa; else father[fa] = fb; if (findFather(n) == 1) { cout << edges[i].dist << endl; return; } } cout << "-1" << endl;} int main() { while (scanf("%d %d", &n, &m) != EOF) { father.resize(n + 1); edges.resize(m); for (int i = 0; i < m; ++i) { scanf("%d %d %d", &edges[i].a, &edges[i].b, &edges[i].dist); } init(); solve(); } return 0;}
也可以用c语言实现#include <stdio.h>#include <stdlib.h>#include <stdlib.h> #define N 20005 typedef struct node { int bt, ed, value;} node; int father[N]; int findSet(int x){ int root; if (x == father[x]) { return x; } root = findSet(father[x]); father[x] = root; return root;} int cmp(const void *p, const void *q){ const node *a = p; const node *b = q; return a->value - b->value;} int main(void){ int i, n, m, pa, pb, flag; node *nodes; while (scanf("%d %d", &n, &m) != EOF) { // 初始化并查集 for (i = 1; i <= n; i ++) { father[i] = i; } nodes = (node *)malloc(sizeof(node) * m); for (i = 0; i < m; i ++) { scanf("%d %d %d", &nodes[i].bt, &nodes[i].ed, &nodes[i].value); } qsort(nodes, m, sizeof(nodes[0]), cmp); for (i = flag = 0; i < m; i ++) { pa = findSet(nodes[i].bt); pb = findSet(nodes[i].ed); if (pa != pb) { father[pa] = pb; } if (findSet(1) == findSet(n)) { flag = 1; printf("%d\n", nodes[i].value); break; } } if (! flag) printf("-1\n"); free(nodes); } return 0;}
另外也可以用BFS然后将队列改为优先队列果断A了
#include<cstdio>#include<cstring>#include<vector>#include<queue>using namespace std;struct node{ int ne; int va;};struct node1{int next;int m;bool operator < (const node1& a) const{return m>a.m;}};vector<node> map[10002];int visit[10002];int n,t,in;int mmin(int aa,int bb){ return aa<bb?aa:bb;}int max(int aa,int bb){ return aa>bb?aa:bb;}int BFS(){int xiao = 1000008;priority_queue<node1> qu;struct node1 needru,needpush,var;needru.next = 1;needru.m = 0;qu.push(needru);visit[1] = 1;while(!qu.empty()){needpush = qu.top();qu.pop();if(needpush.next==n)xiao = mmin(xiao,needpush.m);int len = map[needpush.next].size();visit[needpush.next] = 1;for(int i=0;i<len;i++){if(!visit[map[needpush.next][i].ne]){var.next = map[needpush.next][i].ne;var.m = max(map[needpush.next][i].va,needpush.m);qu.push(var);}}}return xiao;}int main(){ int i,j,a,b; struct node qq; while(scanf("%d%d",&n,&t)!=EOF) { in = 1000008; memset(visit,0,sizeof(visit)); for(i=0;i<t;i++) { scanf("%d%d%d",&a,&b,&j); qq.ne = b; qq.va = j; map[a].push_back(qq); qq.ne = a; map[b].push_back(qq); } visit[1] = 1;in = BFS(); if(in!=1000008) printf("%d\n",in); else printf("-1\n"); for(i=0;i<=n;i++) map[i].clear(); } return 0;}
0 0
- 奇怪的连通图_1545
- 奇怪的连通图
- 题目1545:奇怪的连通图
- 题目1545:奇怪的连通图
- 九度oj 1545奇怪的连通图
- 九度OJ 1545 奇怪的连通图
- 【九度】题目1545:奇怪的连通图
- <九度 OJ>题目1545:奇怪的连通图
- 连通图的强连通分支
- 图的连通
- 图的连通
- 奇怪的传图仓库
- 强连通图的算法
- 求图的连通分量
- 强连通图的算法
- 强连通图的算法
- 强连通图的算法
- 图的强连通分量
- 社説 20150601 スカイマーク なお不透明な再生への道筋
- mysql的语法高亮文件。
- JavaScript动态增删改表格数据
- 安装endnote后word卡解决方法
- mysql主从复制
- 奇怪的连通图_1545
- 在DLL中获取主进程窗口句柄
- storm自带例子详解 (四)——ManualDRPC
- 社説 20150601 関電再値上げ 原発再稼働を着実に推進せよ
- 01-复杂度2. Maximum Subsequence Sum (25)
- 3D数学基础及图形与游戏开发的学习 (三)
- How to make changes to wcf service without breaking clients
- 观察者模式
- MFC让按钮控件显示*.ico图标和文字说明