• 题解 [SDOI2010] 大陆争霸


    题面

    解析

    这题似乎不是那么难啊

    首先,显而易见,

    如果要摧毁一个城市,必须要满足两个条件:

    • 机器人摧毁了保护它的城市.
    • 机器人到达了这个城市.

    而这两个条件可以同时进行(毕竟有无数机器人)

    那么显然,我们只需要在上面的条件的时间取(max)就行了.

    具体来说,我们可以魔改dijkstra,

    (d1[i])是到达(i)的时间,(d2[i])是摧毁保护(i)的所有城市的时间,

    对于保护(j)的城市(i),从(i)(j)连边(新建一张图),就可以更新(d2)了.

    只要城市被摧毁,就将它放到堆里面就行了.

    具体看代码吧:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #define fre(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout)
    using namespace std;
    
    inline int read(){
    	int sum=0,f=1;char ch=getchar();
    	while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0' && ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
    	return f*sum;
    }
    
    const int N=100001;
    struct edge{int to,next,w;}e[N<<1],E[N<<1];
    int n,m;
    int head[N],Head[N],cnt,Cnt;
    int d1[N],d2[N],s[N],v[N];
    priority_queue < pair<int,int> > que;
    
    inline void add(int x,int y,int w){
    	e[++cnt]=(edge){head[x],y,w};head[x]=cnt;
    }
    
    inline void Add(int x,int y,int w){
    	E[++Cnt]=(edge){Head[x],y,w};Head[x]=Cnt;
    }
    
    inline void dij(){
    	memset(d1,0x3f,sizeof(d1));d1[1]=0;
    	que.push(make_pair(0,1));
    	while(!que.empty()){
    		int x=que.top().second,d=-que.top().first;que.pop();
    		if(max(d1[x],d2[x])!=d) continue;
    		if(v[x]) continue;v[x]=1;
    		for(int i=head[x];i;i=e[i].to){
    			int k=e[i].next;
    			if(d1[k]<=d+e[i].w) continue;
    			d1[k]=d+e[i].w;
    			if(!s[k]) que.push(make_pair(-max(d1[k],d2[k]),k));
    		}
    		for(int i=Head[x];i;i=E[i].to){
    			int k=E[i].next;
    			s[k]--;d2[k]=max(d2[k],d);
    			if(!s[k]) que.push(make_pair(-max(d1[k],d2[k]),k));
    		}
    	}
    //	for(int i=1;i<=n;i++) printf("d1[%d]=%d d2[%d]=%d
    ",i,d1[i],i,d2[i]);
    }
    
    int main(){
    	n=read();m=read();
    	for(int i=1;i<=m;i++){int x=read(),y=read(),w=read();add(x,y,w);}
    	for(int i=1;i<=n;i++){
    		s[i]=read();
    		for(int j=1;j<=s[i];j++){int x=read();Add(x,i,0);}
    	}
    	dij();
    	printf("%d
    ",max(d1[n],d2[n]));
    	return 0;
    }
    
    
  • 相关阅读:
    日期格式
    典型的三行两列居中高度自适应div+css布局
    转javascript倒计时例子
    javascript encode64 decode64
    【转】Linux下 zip 和 unzip的用法
    【转】matlab reshape使用
    【转】MySQL修改root密码的各种方法整理
    【转】汇编语言里 eax, ebx, ecx, edx, esi, edi, ebp, esp
    [转]ExtJS xtype class对照表
    vc 字符串转时间,并取时间差
  • 原文地址:https://www.cnblogs.com/zsq259/p/11182356.html
Copyright © 2020-2023  润新知