• codeforces 700C Break Up 暴力枚举边+边双缩点(有重边)


    题意:n个点,m条无向边,每个边有权值,给你 s 和 t,问你至多删除两条边,让s,t不连通,问方案的权值和最小为多少,并且输出删的边

    分析:n<=1000,m是30000  s,t有4种情况(首先定义完全不相同的路径,即两条路径上没有一条边是一样的)

            1. s,t本就不连通,输出0即可

            2. s,t连通但是只有一条完全不相同的路径

            3. s,t连通但是只有两条条完全不相同的路径

            4. s,t连通但是有>=3条完全不相同的路径(这种情况无解)

           情况1预处理即可,要解决的问题是2,3,4乍一看,情况很多,其实可以用枚举法

           首先找出一条从s到t的路径,发现s到t,如果不连通,必须删除这条路径中一条边

           于是可以枚举删除的第一条边,剩下的做边双缩点,这时分开讨论

          (1)删边后,s和t在一个双连通分量,此时符合上述情况4,无解

          (2)本身就不连通,这时只删除枚举的边就好了

          (3)连通的话,找到s连通分量到t连通分量中最小的桥就好了,删除的是枚举的边和最小的桥边

          最终把合法的方案取最小即可

    #include <cstdio>
    #include <vector>
    #include <stack>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int N = 1e3+5;
    const int INF = 1e9+7;
    typedef long long LL;
    int s,t,n,m;
    int a[N*30],b[N*30],c[N*30];
    vector<int>g[N];
    bool ban[30*N];
    int dfn[N],low[N],clk,bel[N],cnt;
    stack<int>st;
    void targin(int u,int f){
      dfn[u]=low[u]=++clk;
      bool flag=0;st.push(u);
      for(int i=0;i<g[u].size();++i){
          if(ban[g[u][i]])continue;
          int v=u==a[g[u][i]]?b[g[u][i]]:a[g[u][i]];
          if(v==f&&!flag){flag=1;continue;}
          if(!dfn[v]){
            targin(v,u);
            low[u]=min(low[u],low[v]);
          }
          else low[u]=min(low[u],dfn[v]);
      }
      if(dfn[u]==low[u]){
        ++cnt;int x;
        do{
          x=st.top();
          st.pop();
          bel[x]=cnt;
        }while(x!=u);
      }
    }
    int path[N*2];
    int vis[N];
    bool find_pre(int u,int d){
      vis[u]=d;
      if(u==t)return true;
      for(int i=0;i<g[u].size();++i){
        int v=u==a[g[u][i]]?b[g[u][i]]:a[g[u][i]];
        if(vis[v])continue;
        path[d]=g[u][i];
        if(find_pre(v,d+1))return true;
      }
      return false;
    }
    vector<int>G[N]; 
    int find_brige(int u,int f,int id){
       if(bel[t]==u)return id;
       for(int i=0;i<G[u].size();++i){
         int x=bel[a[G[u][i]]],y=bel[b[G[u][i]]];
         int v=u==x?y:x;
         if(v==f)continue;
         int tmp=id;if(c[G[u][i]]<c[id])tmp=G[u][i];
         tmp=find_brige(v,u,tmp);
         if(tmp)return tmp;
       }
       return 0; 
    }
    int main(){
        c[0]=INF;
        scanf("%d%d%d%d",&n,&m,&s,&t);
        for(int i=1;i<=m;++i){
           scanf("%d%d%d",&a[i],&b[i],&c[i]);
           if(a[i]!=b[i])
            g[a[i]].push_back(i),g[b[i]].push_back(i);
        }
        if(!find_pre(s,1)){printf("0
    0
    ");return 0;}
        int ans1=-1,id;
        int ans2=-1,id1,id2;
        for(int i=1;i<vis[t];++i){
          ban[path[i]]=true;
          memset(dfn,0,sizeof(dfn));cnt=clk=0;
          for(int j=1;j<=n;++j)if(!dfn[j])targin(j,0);
          if(bel[s]==bel[t]){ban[path[i]]=false;continue;}
          for(int j=0;j<N;++j)G[j].clear();
          for(int j=1;j<=m;++j){
             if(ban[j]||bel[a[j]]==bel[b[j]])continue;
             G[bel[a[j]]].push_back(j);
             G[bel[b[j]]].push_back(j);
          }
          int cur=find_brige(bel[s],0,0);
          if(!cur){
            if(ans1==-1||ans1>c[path[i]])
              ans1=c[path[i]],id=path[i];
          }
          else{
             if(ans2==-1||ans2>c[path[i]]+c[cur]){
               ans2=c[path[i]]+c[cur];
               id1=cur;id2=path[i];
             }
          }
          ban[path[i]]=false;
        }
        if(ans1==-1&&ans2==-1)printf("-1
    ");
        else if(ans1!=-1&&ans2==-1){
           printf("%d
    1
    %d
    ",ans1,id);
        }
        else if(ans1==-1&&ans2!=-1){
           printf("%d
    2
    %d %d
    ",ans2,id1,id2);
        }
        else{
          if(ans1<=ans2)printf("%d
    1
    %d
    ",ans1,id);
          else printf("%d
    2
    %d %d
    ",ans2,id1,id2);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Powershell 音乐播放
    Powershell指令集_2
    Powershell指令集_2
    Powershell 邮件发送
    Powershell 邮件发送
    Oracle 11g 关闭内存自动管理
    Oracle 11g 内存手动管理
    Oracle 内存参数调整
    RESTful三理解
    RESTful三理解
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5705116.html
Copyright © 2020-2023  润新知