• [Aizu2249] Road Construction


    题意:给你一个图,要你按C值构出最小生成树,但要保证1到所有点的最短距离不变

    题解:

    spfa+最小生成树

    每个点都会被唯一与之对应的一条边松弛

    跑一遍spfa,找出所有最短路要经过的边,构最小生成树的时候先选这些边,然后再按C值从小到大加边

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<queue>
     8 #define ll long long
     9 using namespace std;
    10 
    11 const int N = 10010;
    12 const int M = 20010;
    13 
    14 int n,m,e_num,ans,k;
    15 int nxt[M*2],to[M*2],w[M*2],h[N],dis[N],fa[N],pre[N],bl[M*2],val[M*2];
    16 bool in[N];
    17 
    18 struct Node {
    19   int x,y,z,c,f;
    20   bool operator < (const Node &a) const {
    21     return f==a.f?c<a.c:f>a.f;
    22   }
    23 }e[M];
    24 
    25 queue<int> q;
    26 
    27 int gi() {
    28   int x=0,o=1; char ch=getchar();
    29   while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
    30   if(ch=='-') o=-1,ch=getchar();
    31   while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
    32   return o*x;
    33 }
    34 
    35 void add(int x, int y, int z, int c, int id) {
    36   nxt[++e_num]=h[x],to[e_num]=y,w[e_num]=z,bl[e_num]=id,val[e_num]=c,h[x]=e_num;
    37 }
    38 
    39 void spfa() {
    40   memset(dis,63,sizeof(dis));
    41   dis[1]=0,in[1]=1,q.push(1);
    42   while(!q.empty()) {
    43     int u=q.front();
    44     in[u]=0,q.pop();
    45     for(int i=h[u]; i; i=nxt[i]) {
    46       int v=to[i];
    47       if(dis[u]+w[i]<dis[v]) {
    48     pre[v]=i;
    49     dis[v]=dis[u]+w[i];
    50     if(!in[v]) in[v]=1,q.push(v);
    51       }
    52       else if(dis[u]+w[i]==dis[v]) {
    53     if(val[i]<val[pre[v]]) pre[v]=i;
    54       }
    55     }
    56   }
    57 }
    58 
    59 int find(int x) {
    60   return x==fa[x]?x:fa[x]=find(fa[x]);
    61 }
    62 
    63 void init() {
    64   e_num=ans=k=0;
    65   memset(h,0,sizeof(h));
    66   memset(pre,0,sizeof(pre));
    67 }
    68 
    69 int main() {
    70   while(scanf("%d%d", &n, &m) && n+m) {
    71     init();
    72     for(int i=1; i<=m; i++) {
    73       int x=gi(),y=gi(),z=gi(),c=gi();
    74       add(x,y,z,c,i),add(y,x,z,c,i);
    75       e[i]=(Node){x,y,z,c,0};
    76     }
    77     spfa();
    78     for(int i=2; i<=n; i++) {
    79       e[bl[pre[i]]].f=1;
    80     }
    81     sort(e+1,e+m+1);
    82     for(int i=1; i<=n; i++) fa[i]=i;
    83     for(int i=1; i<=m; i++) {
    84       int x=e[i].x,y=e[i].y;
    85       int xx=find(x),yy=find(y);
    86       if(xx==yy) continue;
    87       ans+=e[i].c,fa[yy]=xx,k++;
    88       if(k==n-1) break;
    89     }
    90     printf("%d
    ", ans);
    91   }
    92   return 0;
    93 }
  • 相关阅读:
    Leet_Code_567_字符串排列
    LeetCode_424_替换后的最长字符串
    LeetCode_139_单词拆分
    为Linux 添加自定义命令
    javax.validation 自定义校验器
    MYBatis 动态SQL
    SPRING BOOT 15.1 TEST
    B-树和B+树的应用:数据搜索和数据库索引
    设计模式-代理
    数据结构与算法
  • 原文地址:https://www.cnblogs.com/HLXZZ/p/7574054.html
Copyright © 2020-2023  润新知