zoukankan      html  css  js  c++  java
  • POJ 2831 Can We Build This One:次小生成树【N^2预处理】

    题目链接:http://poj.org/problem?id=2831

    题意:

      给你一个图,每条边有边权。

      然后有q组询问(i,x),问你如果将第i条边的边权改为x,这条边是否有可能在新的最小生成树中。

    题解:

      更改边权相当于新添加了一条边。

      新边在新MST中的充要条件是:

        加入新边后,在原来的MST上形成的环中,有一条旧边的边权>=x。

        (因为如果这样的话,新边可以替换掉那条最大的边)

      所以可以预处理出 maxn[i][j]:在原来的MST上,任意两点间路径上的最大边权。

      dfs即可。

      对于每一个新访问到的节点i,枚举每一个已访问过的节点j,那么:

        maxn[i][j] = maxn[j][i] = max(maxn[j][fa[i]], v[fa[i]][i])

      复杂度O(N^2)。

    AC Code:

      1 #include <iostream>
      2 #include <stdio.h>
      3 #include <string.h>
      4 #include <algorithm>
      5 #include <vector>
      6 #define MAX_N 1005
      7 #define MAX_M 100005
      8 
      9 using namespace std;
     10 
     11 struct E
     12 {
     13     int s;
     14     int t;
     15     int len;
     16     E(int _s,int _t,int _len)
     17     {
     18         s=_s;
     19         t=_t;
     20         len=_len;
     21     }
     22     E(){}
     23     friend bool operator < (const E &a,const E &b)
     24     {
     25         return a.len<b.len;
     26     }
     27 };
     28 
     29 struct Edge
     30 {
     31     int dest;
     32     int len;
     33     Edge(int _dest,int _len)
     34     {
     35         dest=_dest;
     36         len=_len;
     37     }
     38     Edge(){}
     39 };
     40 
     41 int n,m,q;
     42 int s[MAX_M];
     43 int t[MAX_M];
     44 int v[MAX_M];
     45 int par[MAX_N];
     46 int maxn[MAX_N][MAX_N];
     47 bool vis[MAX_N];
     48 vector<E> e;
     49 vector<Edge> edge[MAX_N];
     50 
     51 void read()
     52 {
     53     scanf("%d%d%d",&n,&m,&q);
     54     for(int i=1;i<=m;i++)
     55     {
     56         scanf("%d%d%d",&s[i],&t[i],&v[i]);
     57         e.push_back(E(s[i],t[i],v[i]));
     58     }
     59 }
     60 
     61 void init_union_find()
     62 {
     63     for(int i=1;i<=n;i++)
     64     {
     65         par[i]=i;
     66     }
     67 }
     68 
     69 int find(int x)
     70 {
     71     return par[x]==x ? x : par[x]=find(par[x]);
     72 }
     73 
     74 void unite(int x,int y)
     75 {
     76     int px=find(x);
     77     int py=find(y);
     78     if(px==py) return;
     79     par[px]=py;
     80 }
     81 
     82 bool same(int x,int y)
     83 {
     84     return find(x)==find(y);
     85 }
     86 
     87 int kruskal()
     88 {
     89     init_union_find();
     90     sort(e.begin(),e.end());
     91     int cnt=0;
     92     int res=0;
     93     for(int i=0;i<e.size();i++)
     94     {
     95         E temp=e[i];
     96         if(!same(temp.s,temp.t))
     97         {
     98             cnt++;
     99             res+=temp.len;
    100             unite(temp.s,temp.t);
    101             edge[temp.s].push_back(Edge(temp.t,temp.len));
    102             edge[temp.t].push_back(Edge(temp.s,temp.len));
    103         }
    104     }
    105     return cnt==n-1 ? res : -1;
    106 }
    107 
    108 void dfs(int now)
    109 {
    110     vis[now]=true;
    111     for(int i=0;i<edge[now].size();i++)
    112     {
    113         Edge temp=edge[now][i];
    114         if(!vis[temp.dest])
    115         {
    116             for(int j=1;j<=n;j++)
    117             {
    118                 if(vis[j])
    119                 {
    120                     maxn[j][temp.dest]=maxn[temp.dest][j]=max(maxn[j][now],temp.len);
    121                 }
    122             }
    123             dfs(temp.dest);
    124         }
    125     }
    126 }
    127 
    128 void work()
    129 {
    130     kruskal();
    131     memset(maxn,0,sizeof(maxn));
    132     memset(vis,false,sizeof(vis));
    133     dfs(1);
    134     int i,x;
    135     while(q--)
    136     {
    137         scanf("%d%d",&i,&x);
    138         if(x<=maxn[s[i]][t[i]]) printf("Yes
    ");
    139         else printf("No
    ");
    140     }
    141 }
    142 
    143 int main()
    144 {
    145     read();
    146     work();
    147 }
  • 相关阅读:
    装饰器
    内置函数
    文件操作
    函数
    数据结构[总结笔记]
    汉诺塔解题思路
    springboot事物
    mysql5.7.29 zip包安装教程
    mysql常用语句【转载】
    springboot+mysql+jpa+sharding-jdbc+druid读写分离
  • 原文地址:https://www.cnblogs.com/Leohh/p/8072682.html
Copyright © 2011-2022 走看看