• CF1100E


    i207M给的题

    省选前-小题解合集

    给定一张有向图,每条边有边权。你可以花费边权的代价反转一条边,使得原图中没有环。最小化反转的边权的最大值。

    首先二分,然后考虑判定。

    转化为有些边可以翻转,有些边不可以翻转,使得图中没有环

    我们把不能反向的边拿出来,然后跑拓扑排序判环,如果有环则无解,不然一定有一种方案,加入那些可以改变方向的边而不产生环。

    新加的边方向:拓扑序小的连向拓扑序大的

    有环一定是大的拓扑序连向小的拓扑序有一条边

    而这样是一定没有环的!

    #include<bits/stdc++.h>
    #define reg register int
    #define il inline
    #define numb (ch^'0')
    using namespace std;
    typedef long long ll;
    il void rd(int &x){
        char ch;x=0;bool fl=false;
        while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
        for(x=numb;isdigit(ch=getchar());x=x*10+numb);
        (fl==true)&&(x=-x);
    }
    namespace Miracle{
    const int N=100000+5;
    int n,m;
    struct edge{
        int x,y,z;
    }b[N];
    struct node{
        int nxt,to;
    }e[2*N];
    int hd[N],cnt;
    void add(int x,int y){
        e[++cnt].nxt=hd[x];
        e[cnt].to=y;
        hd[x]=cnt;
    }
    int dfn[N],df;
    int q[N],l,r;
    int du[N];
    int mem[N],tot;
    bool topo(){
        memset(dfn,0,sizeof dfn);
        l=1,r=0;
        df=0;
        for(reg i=1;i<=n;++i){
            if(du[i]==0){
                q[++r]=i;
                dfn[i]=++df;
            }
        }
        while(l<=r){
            int x=q[l++];
            for(reg i=hd[x];i;i=e[i].nxt){
                int y=e[i].to;
                du[y]--;
                if(!du[y]){
                    dfn[y]=++df;
                    q[++r]=y;
                }
            }
        }
        for(reg i=1;i<=n;++i){
            if(!dfn[i]) return false;
        }
        return true;
    }
    bool che(int mid){
        memset(du,0,sizeof du);
        memset(hd,0,sizeof hd);
        cnt=0;
        for(reg i=1;i<=m;++i){
            if(b[i].z>mid){
                add(b[i].x,b[i].y);
                ++du[b[i].y];
            }
        }
        return topo();
    }
    int main(){
        rd(n);rd(m);
        int x,y,z;
        int L=0,R=0;
        for(reg i=1;i<=m;++i){
            rd(x);rd(y);rd(z);R=max(R,z);
            b[i].x=x;b[i].y=y;b[i].z=z;
        }
        int ans=0;
        while(L<=R){
            int mid=(L+R)>>1;
            if(che(mid)){
                ans=mid;R=mid-1;
            }else L=mid+1;
        }
        printf("%d ",ans);
        bool haha=che(ans);
        for(reg i=1;i<=m;++i){
            if(dfn[b[i].x]>dfn[b[i].y]){
                mem[++tot]=i;
            }
        }
        sort(mem+1,mem+tot+1);
        printf("%d
    ",tot);
        for(reg i=1;i<=tot;++i){
            printf("%d ",mem[i]);
        }
        return 0;
    }
    
    }
    signed main(){
        Miracle::main();
        return 0;
    }
    
    /*
       Author: *Miracle*
       Date: 2019/1/16 11:46:04
    */
  • 相关阅读:
    深入MySQL(一):MySQL的组织架构
    使用graalvm nativeimage 快速暴露jar 代码为native 共享库
    SQL注入__布尔盲注和时间盲注 菜鸟
    linux网络配置,无法解析或者打开软件包列表
    django入门视图
    三.面试题
    select,poll,epoll的区别以及使用方法
    Linux从入门到入坑
    品味Spring Cache设计之美
    JAVA_基础篇(1)_JDK 8 的下载、安装与配置
  • 原文地址:https://www.cnblogs.com/Miracevin/p/10275518.html
Copyright © 2020-2023  润新知