zoukankan      html  css  js  c++  java
  • P3588 [POI2015]PUS

    好题


    思路:线段树优化建图+拓扑DP or 差分约束(都差不多);

    提交:3次

    错因:眼瞎没看题,Inf写的0x3f3f3f3f

    题解:

    类似差分约束的模型,(a<b ightarrow aleq b-1 ightarrow b)(a) 连一条权值为 (-1) 的边,跑类似最短路的DP。
    还是想一下之前的总结,我们发现,边权是非正的,并且0边没有形成环,所以一旦有环一定是负环,原问题无解,所以我们可以用拓扑排序去DP解这道题。
    (d[v]=min(d[v],d[u]+w[i])),我们将所有没有确定的值均设成 (1e9) (题目中要求的上界),按照DP的式子,我们跑出来的是每个点的最大值(经过最少的边),若我们发现确定的值被更新的更小了,也是无解。否则有解,直接输出 (d) 数组即可。

    代码:

    #include<bits/stdc++.h>
    #define R register int
    #define ll long long
    using namespace std;
    namespace Luitaryi {
    inline ll g() { register ll x=0,f=1;
    	register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f;
    	do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*f;
    } const int N=500010,Y=6,F=20,Inf=1e9;
    int n,m,s,rt[2],tot,cnt;
    int ls[N*Y],rs[N*Y]; bool flg[N*Y];
    int vr[N*F],nxt[N*F],fir[N*Y],in[N*Y],w[N*F],d[N*Y];
    inline void add(int u,int v,int ww) 
    	{vr[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt,w[cnt]=ww,++in[v];}
    inline void build(int& tr,int l,int r,const int& op) {
    	if(l==r) return void(tr=l); tr=++tot; R md=l+r>>1;
    	build(ls[tr],l,md,op),build(rs[tr],md+1,r,op);
    	(op)?(add(ls[tr],tr,0),add(rs[tr],tr,0))
    			:(add(tr,ls[tr],0),add(tr,rs[tr],0));
    }
    inline void change(int tr,int l,int r,int LL,int RR,const int& op) {
    	if(LL<=l&&r<=RR) return void((op)?(add(tr,tot,0)):(add(tot,tr,-1))); 
    	R md=l+r>>1; if(LL<=md) change(ls[tr],l,md,LL,RR,op); 
    	if(RR>md) change(rs[tr],md+1,r,LL,RR,op);
    }
    inline void topo() { queue<int> q;
    	for(R i=1;i<=tot;++i) if(!flg[i]) d[i]=Inf;
    	for(R i=1;i<=tot;++i) if(!in[i]) q.push(i);
    	while(q.size()) { R u=q.front(); q.pop();
    		for(R i=fir[u];i;i=nxt[i]) { R v=vr[i];
    			if(d[v]>d[u]+w[i]) {
    				if(flg[v]) {return void(puts("NIE"));}
    				d[v]=d[u]+w[i];
    			} if(!--in[v]) q.push(v);
    		}
    	}	for(R i=1;i<=n;++i) if(in[i]||d[i]<=0) return void(puts("NIE"));
    	puts("TAK"); for(R i=1;i<=n;++i) printf("%lld ",d[i]);
    }
    inline void main() {
    	n=g(),s=g(),m=g(); tot=n;
    	for(R i=1,u,w;i<=s;++i) u=g(),d[u]=g(),flg[u]=true;
    	build(rt[0],1,n,0),build(rt[1],1,n,1);
    	for(R i=1,l,r,k,p;i<=m;++i) {
    		p=l=g(),r=g(),k=g(); ++tot;
    		for(R j=1,q;j<=k;++j) { 
    			q=g(); if(q>l) change(rt[0],1,n,p,q-1,0); 
    			p=q+1,change(rt[1],1,n,q,q,1); 
    		} if(p<=r) change(rt[0],1,n,p,r,0);
    	} topo();
    }
    } signed main() {Luitaryi::main(); return 0;}
    

    2019.10.17
    29

  • 相关阅读:
    每日作业
    Bootstrap框架
    每日作业
    前端之jQuery
    css之浮动详解
    sh命令
    shell编程:sed的选项
    linux 创建连接命令 ln -s 软链接
    grep与egrep命令
    Centos之命令搜索命令whereis与which
  • 原文地址:https://www.cnblogs.com/Jackpei/p/11691478.html
Copyright © 2011-2022 走看看