随笔 - 58,  文章 - 0,  评论 - 4,  阅读 - 3296

一、题目描述:

  n 个点,m 条边,带边权。起点为 1,终点为 n。

  求最小割以及在最小割的情况下的最少割的边数。

  2<=n<=32,1<=m<=1e3。


 二、解题思路:

  第一问很好求解,直接最大流即可。

  第二问想不出来,看了题解把我震惊了!简直太妙了!

  设边 i 原本的边权为 w[i],现在我们令新边权 v[i]=w[i]*2e3 +1。

  设跑出来最大流为ans,割了k条边,编号为 a1,a2,...,ak

  所以 ans={i=1nw[ai]}*1e3+k,已知 k<=m<2e3

  那么有 ans/2e3=i=1nw[ai],ans%1e3=k。

  所以第一问答案为 ans/2e3,第二问答案为 ans%2e3。

  这个题可能有重边。用一个 p[i][j] 表示 i 到 j 的边权比较保险。

  算法 EK,时间复杂度最差 O(nm2),但实际上跑的飞快。


 三、完整代码:

复制代码
#include<iostream>
#define N 50
#define M 1010
#define ll long long
using namespace std;
ll n,m,l,r,u1,v1,w1,ans;
ll q[N],w[N],vis[N],pre[N],p[N][N];
struct EDGE{
    ll v,nxt;
}edge[M*2];
ll head[N],cnt=-1;
void add(ll u,ll v)
{
    edge[++cnt].v=v;
    edge[cnt].nxt=head[u];
    head[u]=cnt;
}
bool bfs()
{
    for(ll i=1;i<=n;i++)
        vis[i]=0;
    l=r=1,q[1]=1;
    while(l<=r)
    {
        ll u=q[l];    l++;
        if(u==n) return true;
        for(ll i=head[u];i!=-1;i=edge[i].nxt)
        {
            ll to=edge[i].v;
            if(!vis[to]&&p[u][to]>0)
            {
                vis[to]=1;
                pre[to]=u;
                q[++r]=to;
                w[to]=min(w[u],p[u][to]);
            }
        }
    }
    return false;
}
void Edmonds_Karp()
{
    w[1]=1e18;
    while(bfs())
    {
        ll u=n;
        ans+=w[n];
        while(u!=1)
        {
            p[u][pre[u]]+=w[n];
            p[pre[u]][u]-=w[n];
            u=pre[u];
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0); 
    cin>>n>>m;
    for(ll i=1;i<=n;i++)
        head[i]=-1;
    for(ll i=1;i<=m;i++)
    {
        cin>>u1>>v1>>w1;
        p[u1][v1]+=w1*M+1;
        add(v1,u1);add(u1,v1);
    }
    Edmonds_Karp();
    cout<<ans/M<<" "<<ans%M<<'\n';
    return 0;
}
复制代码

 四、写题心得:

  感觉网络流的题都要有一个特别妙的构思才行。不过这个题做了也真的蛮有收获的。加油!拜拜!

posted on   trh0630  阅读(59)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示