zoukankan      html  css  js  c++  java
  • codeforces #335div2 D. Lazy Student 构造

    #include<bits/stdc++.h>
    #define REP(i,a,b) for(int i=a;i<=b;i++)
    #define MS0(a) memset(a,0,sizeof(a))
    
    using namespace std;
    
    typedef long long ll;
    const int maxn=1000100;
    const int INF=1<<29;
    
    int n,m;
    struct Edge
    {
        int w,is;
        int id;
        friend bool operator<(Edge A,Edge B)
        {
            return A.w==B.w?A.is>B.is:A.w<B.w;
        }
    };Edge e[maxn],ans[maxn];
    
    bool cmp(Edge A,Edge B)
    {
        return A.id<B.id;
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(cin>>n>>m){
            REP(i,1,m) scanf("%d%d",&e[i].w,&e[i].is),e[i].id=i;
            sort(e+1,e+m+1);
            int cur=1,cnt=0;
            int L=1,R=3;
            bool flag=1;
            REP(i,1,m){
                if(e[i].is){
                    ans[++cnt]={cur,cur+1,e[i].id};
                    cur++;
                }
                else{
                    bool tag=0;
                    //cout<<"L="<<L<<" R="<<R<<endl;
                    if(R<=cur&&R-L>=2) tag=1;
                    else{
                        while(R-L<=1&&R<=cur){
                            while(L>=1&&R-L<=1) L--;
                            if(R-L>=2){
                                tag=1;break;
                            }
                            else R++;
                        }
                    }
                    if(!tag){
                        flag=0;break;
                    }
                    ans[++cnt]={L,R,e[i].id};
                    L--;
                    if(L<1) R++,L=R-2;
                }
            }
            sort(ans+1,ans+cnt+1,cmp);
            if(flag){
                REP(i,1,cnt) printf("%d %d
    ",ans[i].w,ans[i].is);
            }
            else puts("-1");
        }
        return 0;
    }
    /**
    构造法的题目比较自由,虽然变化多端,但是还是有一些技巧的。
    构造的关键在于避开繁琐的情况,寻找一种尽可能简单又尽可能接近答案的情况,并加以证明。
    本题中,给定一些边的信息(边权和是否在MST中),求构造出一个符合条件的图,若不存在输出-1。
    由于边的顶点没给,所以符合条件的图不止一种,显然是构造的题目。
    构造的方式千变万化,没有固定的答案,但是我们要尽可能找出比较容易的构造方式,这就需要优先找一些特殊情况。
    显然,MST是链比树更容易构造,至于正确性,先不管。
    再根据MST的性质,联系到kruskal,自然而然地要给边权排序。
    这样解法就出来了:
    从小到大遍历边,如果属于MST,直接加到链的末端,否则,在链上找两个点,由于边是从小到大添加的,所以随便
    找连个点就行,但是要注意不能有重边,而且要避免重复遍历和漏遍历,所以遍历顺序很重要,前面的提交挂在第27个就是
    因为遍历顺序不对,导致有些边没有遍历到,从而得出-1的情况。后来我想了一个解决办法,原来的遍历方式是直接划窗,
    现在改成L向左划,R向右划,先划L再划R,这样就避免了漏遍历。
    
    v8的解法:
    还是从小到大排序
    直接按度数维护点,如果不在MST上,每次取两个度数最小的点,连边,否则加入一个新点。
    中间过程每个点的度数不超过cur-1表示有解。(简单图的每个点的度数不超过n-1).
    这个正确性就显而易见了,,,,orz。。。。
    
    更新:第二种解法需要判重边。。。这样写起来更麻烦了。。。。是非常麻烦。。。。。
    
    */
    View Code
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    C++学习基础十六-- 函数学习笔记
    OpenGL ES平移矩阵和旋转矩阵的左乘与右乘效果
    C++学习基础十五--sizeof的常见使用
    C++学习基础十四——基础类型vector
    XDGE_DefalutLit 物理渲染总结-01
    XDGEUnity XDGEPipeLine
    XDGE Render-启程
    一次BSSDF引发的惨案----搬家狂删除
    XDGE_RayMarchine 1- 利用Frag Shader绘制图形
    XDGE_AccelerationAlgorithms 01
  • 原文地址:https://www.cnblogs.com/--560/p/5036432.html
Copyright © 2011-2022 走看看