【图论综合】电话网络

Description

【图论综合】电话网络_第1张图片

Input

Output

Sample Input

5 7 1
1 2 5
3 1 4
2 4 8
3 2 3
5 2 9
3 4 7
4 5 6

Sample Output

4

Hint

【数据规模】
1 ≤ N ≤ 1000




题解:

    这道题的限制条件很多,初看起来很复杂,无从下手。
    于是,我们先去掉一些限制条件,将题目简化一下:假设没有电信公司的参与,其他条件不变,即是在所有连通1—n 的路径中找出一条,使得这条路径中的边上权值最大值最小的一段。对此我们采用二分枚举最高代价的方法。现假设当前枚举代价为m, 即所有路径中最短的一条最长路长度为m,然后初始化,将这个图中凡是距离大于m 的两个节点赋为不连通,在判断新图的1—n 是否连通。如果连通,说明可行,接下来二分枚举比m小的值,反之亦然。
    接下来考虑有电信公司的参与。基本方法不变,还是二分枚举。假设当前枚举代价为m。
    规定给出的图中,一对电话线杆之间的距离若小于m,则称这条路为一类路,若大于m,则为二类路。求1—N是否连通时,采用最短路Dijkstra(也可以用SPFA)。注意在求最短路时,要记录的不是dist[k]:1—k距离的最小值,而是记录dd[k]:表示1—k的连通路径中经过的最少的二类路。如果dd[n]<=电信公司提供的数目,说明m可行,接下来二分枚举比m小值,反之亦然。

下面上代码:

#include
#include
#define N 1000005
#define inf 0x7fffffff/2
using namespace std;
int n,p,k,Max,cnt,v[N],d[N],q[N],h[N];
struct edge{
	int to,next,v;
}w[1000001];
void addedge(int x,int y,int z)
{
	cnt++;
	w[cnt]=(edge){y,h[x],z};
	h[x]=cnt;
}
void init()
{
	int x,y,z;
	scanf("%d%d%d",&n,&p,&k);
	for(int i=1;i<=p;i++)
	{
		scanf("%d%d%d",&x,&y,&z);
		addedge(x,y,z);addedge(y,x,z);
		Max=max(Max,z);
	}
	//cout<top)
			va=1;else va=0;
			if(d[to]>d[x]+va)
			{
				d[to]=d[x]+va;
				if(!v[to]) {v[to]=1;q[++r]=to;}
			}
		}
	}
//	cout<
仅为个人见解,若有不对之处,多有见谅!

你可能感兴趣的:(【图论综合】电话网络)