您的位置:首页 > 产品设计 > UI/UE

POJ 2831 Can We Build This One?(最小生成树)

2013-12-02 19:33 232 查看
题目链接:http://poj.org/problem?id=2831

题意:

题目大意:给张图,然后问你,如果某边的权值下降为V,那么这个边有无可能在最小生成树中呢?节点数≤1000,边数≤100000,询问数≤100000。

思路:prim。

考虑prim的算法过程:每次加入一个点,并且加入该点的条件是dis[i]是还没加入点的dis[]中最小的。

所以执行prim时,用数组no[]保存某点加入的次序,numm[i]保存第i个加入的点的id

查询边(a,b)时(假设a的加入次序先于b),则枚举no[a]+1 ~ no[b]加入的点的dis[],若存在x<=dis[k],原prim算法过程可被打破,边(a,b)会被选择,

因为该边是当前最佳的边;否则还是原算法过程进行。

1 #include <iostream>
2 #include <cstdio>
3 #include <cmath>
4 #include <cstring>
5 #include <iomanip>
6 using namespace std;
7
8 const int maxd = 1000001;
9 const int N = 1005;
const int M = 1000001;

int map1

, dis
, vis
, no
, numm
;
struct Path
{
int a, b, c;
}p[M];

void prim(int n)
{
int cur;
for(int i=1; i<=n; i++) dis[i] = maxd;
memset(vis, 0, sizeof(vis));
cur = 1; dis[cur] = 0; vis[cur] = 1;
no[cur] = 1; numm[1] = cur;
//找n-1轮
for(int i=2; i<=n; i++)
{
//枚举上一次加入的点与各个点的距离,更新最小距离dis[i]
for(int j=1; j<=n; j++)
{
if(vis[j]==0 && dis[j]>map1[cur][j])
dis[j] = map1[cur][j];
}
//选出最短的边,把该边连接的点加入结果集
int mind = maxd;
for(int j=1; j<=n; j++)
{
if(vis[j]==0 && dis[j]<mind)
{
mind = dis[j];
cur = j;
}
}
vis[cur] = 1;
no[cur] = i;
numm[i] = cur;
}
}

void init(int n)
{
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
map1[i][j] = maxd;
}

int main()
{
int n, m, q, pi, x;
scanf("%d%d%d",&n, &m, &q);
init(n);
for(int i=1; i<=m; i++)
{
scanf("%d%d%d",&p[i].a,&p[i].b,&p[i].c);
if(map1[p[i].a][p[i].b]>p[i].c)
map1[p[i].a][p[i].b] = map1[p[i].b][p[i].a] = p[i].c;
}
//prim走一遍,保存no[],numm[],dis[]
prim(n);

for(int i=1; i<=q; i++)
{
scanf("%d%d",&pi,&x);
int a = no[p[pi].a], b = no[p[pi].b], temp, flag = 0, bno, bnum, sno, snum;
if(a>b){bno = a; bnum = p[pi].a; sno = b; snum = p[pi].b;}
else {bno = b; bnum = p[pi].b; sno = a; snum = p[pi].a;}
//枚举p[pi].a 和 p[pi].b两点之间加入的点
//若x<=dis[],则该边为这轮的最优边,可成为最小生成树中的一边
for(int k=sno+1; k<=bno; k++)
{
if(x<=dis[numm[k]])
{
flag = 1;
break;
}
}
if(flag==1)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: