zoukankan      html  css  js  c++  java
  • [20200730NOIP提高组模拟T3]IOIOI占卜

    题目大意:

      今有五变量,ABCDE者也.构造一字符序列A个'I',B个'O',C个'I',D个'O',E个'I'相接也.现有如下操作:给定变量(l,r),可将区间([l,r])内的'I'反转为'O','O'反转为'I',代价为(r-l+1),请你求出将该序列变为全'I'序列所需的最小代价,若无法变为全'I',则输出(-1).

    solution:

    此题非常神奇,可转化为最短路,下面给出证明.为将此题转化为最短路,我们引进一个辅助的差分序列,(x)处的值表示(x)(x-1)处的值相异或的结果,于是我们每次进行([l,r])操作时,改变的值只有(l)(r+1)处的值,所以我们可以看作在添加一条带权边(<l,r+1,r-l+1>),然后分情况讨论,一一枚举以(A+1,A+B+1,A+B+C+1,A+B+C+D+1,A+B+C+D+E+1)为起点终点符合题目要求的最短路即可.

    code:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<map>
    #define R register
    #define next kdjadskfj
    #define debug puts("mlg")
    #define mod 1000000007
    using namespace std;
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    inline ll read();
    inline void write(ll x);
    inline void writeln(ll x);
    inline void writesp(ll x);
    ll A,B,C,D,E,n; 
    ll to[1000000],head[1000000],next[1000000],tot,w[1000000];
    inline void add(ll x,ll y,ll z){to[++tot]=y;next[tot]=head[x];head[x]=tot;w[tot]=z;}
    ll ans,dist;
    ll dis[1000000];
    bool vis[1000000];
    queue<ll>q;
    
    inline ll spfa(ll S,ll T){
    	while(q.size())q.pop();
    	memset(vis,false,sizeof vis);
    	memset(dis,0x3f,sizeof dis);
    	dis[S]=0;q.push(S);
    	while(q.size()){
    		ll x=q.front();q.pop();vis[x]=false;
    		for(R ll i=head[x],ver;i;i=next[i]){
    			ver=to[i];
    			if(dis[ver]>dis[x]+w[i]){
    				dis[ver]=dis[x]+w[i];
    				if(!vis[ver]){
    					vis[ver]=true;
    					q.push(ver);
    				}
    			}
    		}
    	}
    	return dis[T];
    }
    
    int main(){
    	freopen("card.in","r",stdin);
    	freopen("card.out","w",stdout);
    	A=read()+1;
    	B=read()+A;
    	C=read()+B;
    	D=read()+C;
    	E=read()+D;
    	n=read();
    	for(R ll i=1,l,r;i<=n;i++){
    		l=read();r=read();
    		add(l,r+1,r-l+1);add(r+1,l,r-l+1);
    	}
    	dist=spfa(A,B);
    	ans=dis[0];
    	if(dist<dis[0]) ans=min(ans,dist+spfa(C,D));
    	dist=spfa(A,C); 
    	if(dist<dis[0]) ans=min(ans,dist+spfa(B,D));
    	dist=spfa(A,D);
    	if(dist<dis[0]) ans=min(ans,dist+spfa(B,C));
    	writeln(ans>=dis[0]?-1:ans);
    }
    inline ll read(){ll x=0,t=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') t=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*t;}
    inline void write(ll x){if(x<0){putchar('-');x=-x;}if(x<=9){putchar(x+'0');return;}write(x/10);putchar(x%10+'0');}
    inline void writesp(ll x){write(x);putchar(' ');}
    inline void writeln(ll x){write(x);putchar('
    ');}
    
  • 相关阅读:
    ROSS仿真系统简单教程
    python小练习1.1
    c语言文件I/O 文件读取和写入
    Python 学习笔记 多线程-threading
    parsec(The parsec benchmark suit )使用教程
    Checkpoint/Restore In Userspace(CRIU)使用细节
    Checkpoint/Restore in Userspace(CRIU)安装和使用
    考研总结
    北理计算机复试经验
    PAT(A) 1075. PAT Judge (25)
  • 原文地址:https://www.cnblogs.com/ylwtsq/p/13403936.html
Copyright © 2011-2022 走看看