• BZOJ 3691 游行


    题目传送门

    分析:

    没被访问的点要C费用,跑一次路要C费用

    把这两个统一一下试试。。。

    那就是每次不标记起点或者终点

    那就是路径覆盖了2333

    二分图,x 部 i 号点与 y 部 j 号点连 i 到 j 的最短路

    然后每个点都会被访问到

    但是有些的代价会大于C

    那些就干脆不访问了吧2333

    看看费用流的函数特征

    是一个单增函数

    某一刻一单位流的代价大于了C,那就可以停止了

    由于C会变,先求出整个的费用流函数,每次二分查找就好了

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    
    #define maxn 2005
    #define maxm 200005
    #define INF 0x3f3f3f3f
    
    using namespace std;
    
    inline int getint()
    {
        int num=0,flag=1;char c;
        while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
        while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
        return num*flag;
    }
    
    int n,m,Q;
    int S,T;
    int fir[maxn],nxt[maxm],to[maxm],cnt;
    int cap[maxm],cst[maxm];
    int dis[maxn];
    int vis[maxn],pre[maxn];
    int sum[maxn],tot;
    int D[maxn][maxn];
    
    inline void newnode(int u,int v,int w,long long c)
    {to[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt,cap[cnt]=w,cst[cnt]=c;}
    inline void insert(int u,int v,int w,long long c)
    {newnode(u,v,w,c),newnode(v,u,0,-c);}
    
    inline bool spfa()
    {
        memset(dis,INF,sizeof dis);dis[S]=0;
        memset(pre,-1,sizeof pre);
        queue<int>Q;Q.push(S),vis[S]=1;
        while(!Q.empty())
        {
            int u=Q.front();Q.pop();vis[u]=0;
            for(int i=fir[u];i;i=nxt[i])
                if(cap[i]&&dis[to[i]]>dis[u]+cst[i])
                {
                    dis[to[i]]=dis[u]+cst[i];pre[to[i]]=i^1;
                    if(!vis[to[i]])vis[to[i]]=1,Q.push(to[i]);
                }
        }
        return ~pre[T];
    }
    
    inline int dinic()
    {
        int num=0;
        while(spfa())
        {
            tot++;
            sum[tot]=sum[tot-1];
            int mn=INF;
            for(int i=pre[T];i!=-1;i=pre[to[i]])mn=min(mn,cap[i^1]);
            int tmp=0;
            for(int i=pre[T];i!=-1;i=pre[to[i]])cap[i]+=mn,cap[i^1]-=mn,tmp+=cst[i^1];
            sum[tot]+=tmp*mn,num+=mn;
        }
        return num;
    }
    
    int main()
    {
        n=getint(),m=getint(),Q=getint();
        S=n*2+1,T=S+1,cnt=1;
        memset(D,INF,sizeof D);
        for(int i=1;i<=n;i++)D[i][i]=0;
        for(int i=1;i<=m;i++)
        {
            int u=getint(),v=getint();
            D[u][v]=min(getint(),D[u][v]);
        }
        for(int k=1;k<=n;k++)for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)
            D[i][j]=min(D[i][j],D[i][k]+D[k][j]);
        for(int i=1;i<=n;i++)insert(S,i,1,0),insert(i+n,T,1,0);
        for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)if(i^j)insert(i,j+n,1,D[i][j]);
        dinic();
        while(Q--)
        {
            int C=getint(),l=1,r=tot,ans=0;
            while(l<=r)
            {
                int mid=(l+r)>>1;
                if(sum[mid]-sum[mid-1]<C)l=mid+1,ans=mid;
                else r=mid-1;
            }
            printf("%d
    ",sum[ans]+(n-ans)*C);
        }
    }
    View Code

  • 相关阅读:
    mysql的安装
    一个电脑登录多个微信
    项目工程构建
    MYSQL 添加字段
    Centos 搭建maven私服
    Nacos 动态刷新@RefreshScope
    Cookie & Session
    阿里蚂蚁 笔试题
    springboot 将配置文件中的配置读取为properties配置类
    .Net Gacutil工具(全局程序集缓存工具)使用教程
  • 原文地址:https://www.cnblogs.com/Darknesses/p/12040346.html
Copyright © 2020-2023  润新知