zoukankan      html  css  js  c++  java
  • UOJ 486 在路上了

    考虑除开(1-k)以外的任意点(d)在长度为(k-1)的链上有:

    对于任意(i,i+1 (iin [1,k-1]))(col[d][i]+col[d][i+1]<2),否则我们可以直接输出一个红色的(k)条边的链。

    30pts

    (2k=n)的时候,我们考虑两个点(p,q),如果两者之间是(0)直接连上去,如果是1则我们考虑在(1-k)中选两个点(a,a+1),查询(p或q)->(a或a+1) 的颜色。发现我们一定能找到一条p -> (a或a+1) -> q的路径,否则可以输出红边的答案。

    70pts

    30pts的问题主要是如果每次第一次查询颜色都是蓝色则会导致长度不够,考虑三个点p,q,r的时候,我们查寻(6)次,至少有(3)(0)边,也就是说至少可以让两个点中间插两条边。

    这样我们可以变成只剩两条链。用一个端点链接变成一条链

    如果是(1/2k)(>k)的点,现在会剩下3个点,一个是端点,发现正好可以在两边多拓展一个,这样刚好可以凑出来一个(k)条边的。

    100pts

    (6)次查询优化成(4)次即可。先查p->a,q->a,如果同色,则最多再花两次询问找一个。如果不同色,则查询r->a+1,之后无论如何都只用再查询一次。这样最多查询(4)

    代码

    #include <bits/stdc++.h>
    #include "graph.h"
    using namespace std;
    typedef pair<int,int> pii;
    map<pair<int,int>, int> table;
    inline int qry(int x,int y){
    	if(x>y)swap(x,y);
    	if(table.find(pii(x,y))==table.end())
    		return table[pii(x,y)]=query(x,y);
    	else return table[pii(x,y)];
    }
    int KK;
    struct link{
    	int s,t;
    	vector<int> node;
    	link(int s=0,int t=0):s(s),t(t){node.push_back(s);}
    	void rev(){
    		reverse(node.begin(),node.end());
    		swap(s,t);
    	}
    	inline void add(link y){
    		t=y.t;
    		for(size_t i=0;i<y.node.size();i++)node.push_back(y.node[i]);
    	}
    };
    vector<link> Lk;
    int curpos;
    vector<int> Ret;
    vector<int> gen(int p,int d){
    	vector<int> r;
    	for(int i=0;i<=KK;i++){
    		if(i>0)r.push_back(i);
    		if(i==p)r.push_back(d);
    	}
    	return r;
    }
    void push_back(link t){
    	Lk.push_back(t);
    }
    bool End;
    inline void merge(link a,link b,link c){
    	link nw;
    	int d1=qry(a.s,curpos-1);
    	int d2=qry(b.s,curpos-1);
    	if(d1==d2&&d2==0){
    		nw=a;nw.rev();nw.node.push_back(curpos-1);
    		nw.add(b);
    		push_back(c);push_back(nw);
    		return ;
    	}
    	else if(d1==d2&&d2==1){
    		if(qry(a.s,curpos)==1){
    			Ret=gen(curpos-1,a.s);
    			End=1;return ;
    		}if(qry(b.s,curpos)==1){
    			Ret=gen(curpos-1,b.s);
    			End=1;return ;
    		}
    		nw=a;nw.rev();nw.node.push_back(curpos);
    		nw.add(b);
    		push_back(c);push_back(nw);
    	}
    	else{
    		int d3=qry(c.s,curpos);
    		if(d1==1)
    			swap(a,b);//d1=0,d2=1
    		if(!d3){
    			if(qry(b.s,curpos)==1){
    				Ret=gen(curpos-1,b.s);
    				End=1;return ;
    			}
    			nw=b;nw.rev();nw.node.push_back(curpos);
    			nw.add(c);
    			push_back(a),push_back(nw);
    		}else{
    			if(qry(c.s,curpos-1)==1){
    				Ret=gen(curpos-1,c.s);End=1;
    				return;
    			}
    			nw=a;nw.rev();nw.node.push_back(curpos-1);
    			nw.add(c);
    			push_back(b),push_back(nw);
    		}
    	}
    }
    bool sp=0;
    vector<int> find_longer_path(int n, int k) {
    	KK=k;
    	int n2=(k-1)/2+2;
    	if(k+n2>n)n2--,sp=1;
    	for(int j=k+1;j<=k+n2;j++){
    		Lk.push_back(link(j,j));
    	}
    	curpos=3;
    	while((int)Lk.size()>2){
    		link a=Lk.back();Lk.pop_back();
    		link b=Lk.back();Lk.pop_back();
    		link c=Lk.back();Lk.pop_back();
    		merge(a,b,c);
    		if(End)return Ret;
    		curpos+=2;
    	}
    	link a=Lk[0], b=Lk[1];
    	if(qry(a.s,1))return gen(0,a.s);
    	if(qry(b.s,1))return gen(0,b.s);
    	a.rev();a.node.push_back(1);a.add(b);
    	if((int)a.node.size()>=k+1){
    		while((int)a.node.size()>k+1)a.node.pop_back();
    		return a.node;
    	}else{
    		if(qry(a.t,k)){
    			return gen(k,a.t);
    		}
    		a.node.push_back(k);a.t=k;
    		if(a.node.size()<k+1){
    			a.rev();
    			int d2=qry(k-1,a.t);
    			int d3=qry(k-2,a.t);
    			if(d2&&d3)return gen(k-2,a.t);
    			else if(!d2){
    				a.node.push_back(k-1);
    			}else if(!d3){
    				a.node.push_back(k-2);
    			}
    		}
    		return a.node;
    	}
    }
    
  • 相关阅读:
    第7次实践作业 25组
    第6次实践作业 25组
    第5次实践作业
    第4次实践作业
    第3次实践作业
    第2次实践作业
    第1次实践作业
    软工实践个人总结
    2019 SDN大作业
    C语言Il作业01
  • 原文地址:https://www.cnblogs.com/weiyanpeng/p/11340758.html
Copyright © 2011-2022 走看看