• BZOJ2229: [Zjoi2011]最小割


    题解:

    真是一道神题!!!

    大家还是围观JZP的题解吧(网址找不到了。。。)

    代码:

      1 #include<cstdio>
      2   
      3 #include<cstdlib>
      4   
      5 #include<cmath>
      6   
      7 #include<cstring>
      8   
      9 #include<algorithm>
     10   
     11 #include<iostream>
     12   
     13 #include<vector>
     14   
     15 #include<map>
     16   
     17 #include<set>
     18   
     19 #include<queue>
     20   
     21 #include<string>
     22   
     23 #define inf 1000000000
     24   
     25 #define maxn 200000+5
     26   
     27 #define maxm 200000+5
     28   
     29 #define eps 1e-10
     30   
     31 #define ll long long
     32   
     33 #define pa pair<int,int>
     34   
     35 #define for0(i,n) for(int i=0;i<=(n);i++)
     36   
     37 #define for1(i,n) for(int i=1;i<=(n);i++)
     38   
     39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
     40   
     41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
     42   
     43 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
     44   
     45 #define for5(n,m) for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
     46   
     47 #define mod 1000000007
     48   
     49 using namespace std;
     50   
     51 inline int read()
     52   
     53 {
     54   
     55     int x=0,f=1;char ch=getchar();
     56   
     57     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     58   
     59     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
     60   
     61     return x*f;
     62   
     63 }
     64 int  n,m,s,t,cut[200][200],a[maxm],b[maxm],c[maxm],maxflow,tot=1,head[maxn],cur[maxn],h[maxn];
     65   
     66 queue<int>q;
     67 bool v[maxn];
     68   
     69 struct edge{int go,next,v;}e[maxm];
     70   
     71 inline void add(int x,int y,int v)
     72   
     73 {
     74   
     75     e[++tot]=(edge){y,head[x],v};head[x]=tot;
     76   
     77     e[++tot]=(edge){x,head[y],0};head[y]=tot;
     78   
     79 }
     80   
     81 bool bfs()
     82   
     83 {
     84   
     85     for(int i=1;i<=n;i++)h[i]=-1;
     86   
     87     q.push(s);h[s]=0;
     88   
     89     while(!q.empty())
     90   
     91     {
     92   
     93         int x=q.front();q.pop();
     94   
     95         for(int i=head[x];i;i=e[i].next)
     96   
     97          if(e[i].v&&h[e[i].go]==-1)
     98   
     99          {
    100   
    101             h[e[i].go]=h[x]+1;q.push(e[i].go);
    102   
    103          }
    104   
    105     }
    106   
    107     return h[t]!=-1;
    108   
    109 }
    110   
    111 int dfs(int x,int f)
    112   
    113 {
    114   
    115     if(x==t) return f;
    116   
    117     int tmp,used=0;
    118   
    119     for(int i=cur[x];i;i=e[i].next)
    120   
    121      if(e[i].v&&h[e[i].go]==h[x]+1)
    122   
    123     {
    124   
    125         tmp=dfs(e[i].go,min(e[i].v,f-used));
    126   
    127         e[i].v-=tmp;if(e[i].v)cur[x]=i;
    128   
    129         e[i^1].v+=tmp;used+=tmp;
    130   
    131         if(used==f)return f;      
    132   
    133     }
    134   
    135     if(!used) h[x]=-1;
    136   
    137     return used;
    138   
    139 }
    140 inline void dfs(int x)
    141 {
    142     v[x]=1;
    143     for4(i,x)if(e[i].v&&!v[y])dfs(y);
    144 }
    145   
    146 void dinic()
    147   
    148 {
    149     maxflow=0;
    150   
    151     while(bfs())
    152   
    153     {
    154   
    155         for (int i=1;i<=n;i++)cur[i]=head[i];maxflow+=dfs(s,inf);
    156   
    157     }
    158   
    159 }
    160 inline void solve(int l,int r)
    161 {
    162     if(l==r)return;
    163     s=b[l];t=b[r];
    164     for1(i,tot)e[i].v=a[i];
    165     dinic();
    166     for1(i,n)v[i]=0;
    167     dfs(s);
    168     for1(i,n)if(v[i])for1(j,n)if(!v[j])cut[i][j]=cut[j][i]=min(cut[i][j],maxflow);
    169     int t1=l-1,t2=r+1;
    170     for2(i,l,r)if(v[b[i]])c[++t1]=b[i];else c[--t2]=b[i];
    171     for2(i,l,r)b[i]=c[i];
    172     solve(l,t1);solve(t2,r);
    173 }
    174   
    175 int main()
    176   
    177 {
    178     int T=read();
    179     while(T--)
    180     {
    181         n=read();m=read();
    182         for1(i,n)head[i]=0;tot=1;
    183         for1(i,m)
    184         {
    185             int x=read(),y=read(),w=read();
    186             add(x,y,w);add(y,x,w);
    187         }
    188         for1(i,tot)a[i]=e[i].v;
    189         for1(i,n)b[i]=i;
    190         for1(i,n)for1(j,n)cut[i][j]=inf;
    191         solve(1,n);
    192         int q=read();
    193         while(q--)
    194         {
    195             int x=read(),ans=0;
    196             for1(i,n)for2(j,i+1,n)if(cut[i][j]<=x)ans++;
    197             printf("%d
    ",ans);
    198         }
    199         printf("
    ");
    200     }
    201   
    202     return 0;
    203   
    204 }  
    View Code

    2229: [Zjoi2011]最小割

    Time Limit: 10 Sec  Memory Limit: 259 MB
    Submit: 685  Solved: 263
    [Submit][Status]

    Description

    小 白在图论课上学到了一个新的概念——最小割,下课后小白在笔记本上写下了如下这段话: “对于一个图,某个对图中结点的划分将图中所有结点分成两个部分,如果结点s,t不在同一个部分中,则称这个划分是关于s,t的割。 对于带权图来说,将所有顶点处在不同部分的边的权值相加所得到的值定义为这个割的容量,而s,t的最小割指的是在关于s,t的割中容量最小的割” 现给定一张无向图,小白有若干个形如“图中有多少对点它们的最小割的容量不超过x呢”的疑问,小蓝虽然很想回答这些问题,但小蓝最近忙着挖木块,于是作为 仍然是小蓝的好友,你又有任务了。

    Input

    输入文件第一行有 且只有一个正整数T,表示测试数据的组数。 对于每组测试数据, 第一行包含两个整数n,m,表示图的点数和边数。 下面m行,每行3个正整数u,v,c(1<=u,v<=n,0<=c<=106),表示有一条权为c的无向边(u,v) 接下来一行,包含一个整数q,表示询问的个数 下面q行,每行一个整数x,其含义同题目描述。

    Output

    对于每组测试数据,输出应包括q行,第i行表示第i个问题的答案。对于点对(p,q)和(q,p),只统计一次(见样例)。

    两组测试数据之间用空行隔开。

    Sample Input

    1
    5 0
    1
    0

    Sample Output

    10

    【数据范围】
    对于100%的数据 T<=10,n<=150,m<=3000,q<=30,x在32位有符号整数类型范围内。
    图中两个点之间可能有多条边

    HINT

    Source

  • 相关阅读:
    可编辑的div -> 编辑框
    图片的缩放处理
    枚举转换成字典集合的通用方法
    SQLPrompt_9.5.5.9830破解版含注册机_永久激活不掉线
    配置阿里云docker镜像地址
    Virtualbox设置固定IP
    史上最全的 vi 命令大全,建议手册
    ASP.NET Core WebApi使用Swagger生成api说明文档看这篇就够了
    vue Slot理解
    windows上pip安装及使用详解
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4194250.html
Copyright © 2020-2023  润新知