• BNUOJ-26586 Simon the Spider 最小生成树+枚举


      题目链接:http://www.bnuoj.com/bnuoj/problem_show.php?pid=26586

      题意:给一个图,每条边有一个权值。要你求选择一棵树,权值和为sum,然后在树上选择一条边权值为w,然后使得sum-2*w最小。

      首先求一遍最小生成树,然后求出每两个点之间的最小瓶颈路,然后枚举边就行了。。  

      1 //STATUS:C++_AC_916MS_30048KB
      2 #include <cmath>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <iostream>
      6 #include <algorithm>
      7 using namespace std;
      8 #define mem(a,b) memset(a,b,sizeof(a))
      9 typedef long long LL;
     10 
     11 const int N=2010;
     12 
     13 struct Edge{
     14     int u,v,w;
     15 }e[1000010],et[2000010];
     16 int first[N],next[2000010];
     17 int p[N],vis[N],d[N][N];
     18 bool mst[1000010];
     19 int n,m,mt;
     20 
     21 void adde(int a,int b,int c)
     22 {
     23     et[mt].u=a,et[mt].v=b,et[mt].w=c;
     24     next[mt]=first[a];first[a]=mt++;
     25     et[mt].u=b,et[mt].v=a,et[mt].w=c;
     26     next[mt]=first[b];first[b]=mt++;
     27 }
     28 
     29 int cmp(const Edge& a,const Edge& b)
     30 {
     31     return a.w<b.w;
     32 }
     33 
     34 int find(int x){return p[x]==x?x:p[x]=find(p[x]);}
     35 
     36 int Kruskal()
     37 {
     38     int i,j,x,y,sum=0,cnt=0;
     39     for(i=1;i<=n;i++)p[i]=i;
     40     sort(e,e+m,cmp);
     41     mem(mst,0);
     42     for(i=0;i<m;i++){
     43         x=find(e[i].u);
     44         y=find(e[i].v);
     45         if(x!=y){
     46             cnt++;
     47             sum+=e[i].w;
     48             p[y]=x;
     49             mst[i]=true;
     50         }
     51     }
     52     if(cnt<n-1)return -1;
     53     return sum;
     54 }
     55 
     56 int dfs(int& s,int u,int fa,int hig)
     57 {
     58     int i,v;
     59     for(i=first[u];i!=-1;i=next[i]){
     60         v=et[i].v;
     61         if(v==fa)continue;
     62         d[s][v]=max(hig,et[i].w);
     63         dfs(s,v,u,d[s][v]);
     64     }
     65     return 0;
     66 }
     67 
     68 int main(){
     69  //   freopen("in.txt","r",stdin);
     70     int i,j;
     71     while(~scanf("%d%d",&n,&m))
     72     {
     73         for(i=0;i<m;i++){
     74             scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
     75         }
     76 
     77         int sum;
     78         if((sum=Kruskal())==-1){
     79             printf("disconnected
    ");
     80             continue;
     81         }
     82         mem(first,-1);mt=0;
     83         for(i=0;i<m;i++){
     84             if(mst[i]){
     85                 adde(e[i].u,e[i].v,e[i].w);
     86             }
     87         }
     88         mem(d,0);
     89         for(i=1;i<=n;i++){
     90             dfs(i,i,-1,0);
     91         }
     92         int ans=0x7FFFFFFF;
     93         for(i=0;i<m;i++){
     94             ans=min(ans,sum-d[e[i].u][e[i].v]-e[i].w);
     95         }
     96 
     97         printf("%d
    ",ans);
     98     }
     99     return 0;
    100 }
  • 相关阅读:
    poj 1860 最短路—Bellman-Ford算法
    poj 3083 dfs+bfs最短路
    poj 2049 Finding Nemo(bfs+优先队列)
    Codeforces 685B 树形dp
    Codeforces 679B
    hdu 5695 拓扑排序裸题
    hdu 5690 矩阵快速幂/循环节
    《概率》第一卷( 修订和补充第三版)施利亚耶夫著 周概荣译本 勘误
    HDU 2124 Repair the Wall
    HDU 1198 Farm Irrigation
  • 原文地址:https://www.cnblogs.com/zhsl/p/3284083.html
Copyright © 2020-2023  润新知