POJ2831(次小生成树问题)

Can We Build This One?

Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 1475   Accepted: 546
Case Time Limit: 2000MS

Description

“Highways are built, then life is rich.” Now people of Big Town want to become rich, so they are planning to build highways to connect their villages.

Big Town is really big and has many villages. Its people plan to build some highways between some pairs of villages so that every pair of villages is connected by the highways either directly or indirectly. After surveying the geographical surroundings, they find that there are some paths along with highways can be built. Every path is denoted by a triplet (abc) which means a highway can built between the a-th village and the b-th village with a cost of c. In order to save money, they will select only part of the paths to build highways along so that the total cost to build highways along the selected paths is minimal under the condition that every pair of villages is connected.

It is possible that multiple such selections exist. People from every village want to have those highways of good interest to them built. But some highways can never appear in the selection since they are much too costly. So people ask whether a certain highway can be selected if they agree to cut the cost. Your task is to design a program to answer their queries.

Input

The first line of input contains three integers NM and Q (1 < N ≤ 1,000, N − 1 ≤ M ≤ 100,000, 0 < Q ≤ 100,000), where N is the number of villages, M is the number of paths, and Q is the number of queries. Each of the next M lines contains three integers ab, and c (1 ≤ ab ≤ Na ≠ b, 0 ≤ c ≤ 1,000,000). The triplet (abc) describes a path. Each of following Q lines contains two integer i and x (1 ≤ i ≤ M, 0 ≤ x) describing a query, “Can a highway be built along the i-th path if the cost of is reduced to x?” x is strictly lower than the original cost of building a highway along the i-th path. It is assumed that every pair of village will be connected either directly or indirectly if all possible highways are built. And there may be more than one highway that can be built between a pair of villages.

Output

Output one line for each query. Output either “Yes” or “No” as the answer to the the query.

Sample Input

3 4 3
1 2 10
1 3 6
2 3 4
1 3 7
4 6
1 7
1 5

Sample Output

Yes
No
Yes

思路:查询第i条边时,比较边的两个端点在(u,v)在树中的最长路与第i条边修改后值的大小。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN=1005;
const int INF=0x3f3f3f3f;
struct Node{
    int u,v;
}es[100005];
int tot;

int arc[MAXN][MAXN];
int n,m,q;

int d[MAXN],vis[MAXN],pre[MAXN];
int dp[MAXN][MAXN];
void prim(int src)
{
    memset(pre,0,sizeof(pre));
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=n;i++)
    {
        d[i]=INF;
        vis[i]=0;
    }
    d[src]=0;
    int t=n;
    while(t--)
    {
        int mincost=INF;
        int k;
        for(int i=1;i<=n;i++)
        {
            if(!vis[i]&&mincost>d[i])
            {
                mincost=d[i];
                k=i;
            }
        }
        vis[k]=1;
        int fa=pre[k];
        for(int i=1;i<=n;i++)
        {
            if(vis[i]&&i!=k)
            {
                dp[k][i]=dp[i][k]=max(dp[i][fa],mincost);
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(!vis[i]&&d[i]>arc[i][k])
            {
                d[i]=arc[i][k];
                pre[i]=k;
            }
        }
    }
}

int main()
{
    while(scanf("%d%d%d",&n,&m,&q)!=EOF)
    {
        tot=0;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if(i==j)    arc[i][j]=0;
                else arc[i][j]=INF;
        for(int i=0;i<m;i++)
        {
            int w;
            ++tot;
            scanf("%d%d%d",&es[tot].u,&es[tot].v,&w);
            arc[es[tot].u][es[tot].v]=arc[es[tot].v][es[tot].u]=min(arc[es[tot].v][es[tot].u],w);
        }
        prim(1);
        while(q--)
        {
            int id,w;
            scanf("%d%d",&id,&w);
            if(w<=dp[es[id].u][es[id].v])
            {
                printf("Yes\n");
            }
            else
            {
                printf("No\n");
            }
        }
    }
    return 0;
}
时间: 2024-10-08 09:48:12

POJ2831(次小生成树问题)的相关文章

次短路径与次小生成树问题的简单解法——转自:BYVoid

次短路径与次小生成树问题的简单解法 [次短路径] 次短路径可以看作是k短路径问题的一种特殊情况,求k短路径有Yen算法等较为复杂的方法,对于次短路径,可以有更为简易的方法.下面介绍一种求两个顶点之间次短路径的解法. 我们要对一个有向赋权图(无向图每条边可以看作两条相反的有向边)的顶点S到T之间求次短路径,首先应求出S的单源最短路径.遍历有向图,标记出可以在最短路径上的边,加入集合K.然后枚举删除集合K中每条边,求从S到T的最短路径,记录每次求出的路径长度值,其最小值就是次短路径的长度. 在这里我

非严格/严格次小生成树问题

转载自新博客:https://acxblog.site/archives/smst-problem.html Problem BZOJ 入门OJ P1634 Luogu P4180 BJWC 次小生成树 Introduction 首先讲非严格次小生成树的做法. 先建立权值之和为\(W\)的最小生成树.接着枚举没有被并入到MST的边(u,v)(我们将把这条边加入到MST中,并在原MST中删去一条最大边,使新ST仍然联通),权值为\(W_e\).查询树上u->v的路径,在路径选取一个边权最大值\(W

次短路径与次小生成树问题的简单解法

[次短路径] 次短路径可以看作是k短路径问题的一种特殊情况,求k短路径有Yen算法等较为复杂的方法,对于次短路径,可以有更为简易的方法.下面介绍一种求两个顶点之间次短路径的解法. 我们要对一个有向赋权图(无向图每条边可以看作两条相反的有向边)的顶点S到T之间求次短路径,首先应求出S的单源最短路径.遍历有向图,标记出可以在最短路径上的边,加入集合K.然后枚举删除集合K中每条边,求从S到T的最短路径,记录每次求出的路径长度值,其最小值就是次短路径的长度. 在这里我们以为次短路径长度可以等于最短路径长

次短路和次小生成树、

转载:传送门 次短路径与次小生成树问题的简单解法 [次短路径] 次短路径可以看作是k短路径问题的一种特殊情况,求k短路径有Yen算法等较为复杂的方法,对于次短路径,可以有更为简易的方法.下面介绍一种求两个顶点之间次短路径的解法. 我们要对一个有向赋权图(无向图每条边可以看作两条相反的有向边)的顶点S到T之间求次短路径,首先应求出S的单源最短路径.遍历有向图,标记出可以在最短路径上的边,加入集合K.然后枚举删除集合K中每条边,求从S到T的最短路径,记录每次求出的路径长度值,其最小值就是次短路径的长

poj 1679 The Unique MST (次小生成树)

The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 20293   Accepted: 7124 Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spanning Tree): Consider a connected, undire

10.05-10.11

//本周依旧做一下图算法的题目,尽量少用algorithm里的函数,自己写熟悉熟悉. 1.The Unique MST 解析:该题为次小生成树问题. 次小生成树的求解过程: 1.找到最小生成树,值为mst 2.最小生成树种的点:找到每一个点到其它点的路径上的最大边权值 dp[i][j]表示i到j路径上的最大边权值 3.加一条不在最小生成树上的边.比如i - k,同时删除在最小生成树上i -> k路径上最大的一个边权值dp[i][k]; 这样会得到 new_mst,在这些new_mst中找一个最小

2014.first

之后就按照自己的直觉,整理了第一套,难度为简单,差不多比2013noipday1水一点...先练练手而已 T1 vijos1196吃糖果游戏 博弈论 依题意,我们可知,如果去分数目为2,3,7,8必输,分4,5,6必赢,或是有出现1则必赢 以此类推,多写几个我们会发现n mod 5=0,1,4则先手必赢 然后依照以上思路模拟,注意一下精度即可 附上代码: #include <cstdio> #include <cstring> #include <algorithm>

最小瓶颈路与次小生成树

简介: 最小生成树是图论里面一类经典问题,可以有很多种变形,其中最小瓶颈路和次小生成树就是两种比较经典的变形.最小瓶颈路就是在两个结点之间求一条最长边最短的路径,而次小生成树则是所有生成树中权值排名第二的生成树(可以和最小生成树相等).下面我们分别来看看这两个问题. 最小瓶颈路: 给定一个加权无向图,并给定无向图中两个结点u和v,求u到v的一条路径,使得路径上边的最大权值最小.这个问题可以稍微加强一下,即求很多对结点之间的最小瓶颈路. 无向图中,任意两个结点的最小瓶颈路肯定在最小生成树上.因此,

关于最小生成树问题

我们通过一个例子来看一下最小生成树的求法. 分别用普里姆算法(从A结点开始)和克鲁斯卡尔算法计算下图的最小生成树. ok,首先运用Prim算法进行计算: U V-U B C D E F TE {A} {B,C,D,E,F} AB 11 AC 13 ~ ∞ AE 16 ~ ∞ AB 11 {A,B} {C,D,E,F}   BC 7 BD 3 AE 16 BF 5 BD 3 {A,B,D} {C,E,F}   BC 7   AE 16 BF 5 BF 5 {A,B,D,F} {C,E}   BC