zoukankan      html  css  js  c++  java
  • BZOJ2330: [SCOI2011]糖果

    显然可以差分约束,但是n,m<=1e5,且有两个数据如下:

    1. 1->2->...->n的一条链。若1先入队,则可以一次更新完。否则每次编号较小的点会把所有编号大于它的点都重新更新一次,就卡到了o(n^2)。若一般的边表按1->n加边,入队顺序就是n->1。面向数据地,可以倒着加边,或者按1->n先把所有点入队。
    2. 有负环的大数据。由于spfa判负环是O(nm)的,所以这个点要跑5s。然而这个点存在负的自环,可以直接判掉……

    有一个tarjan缩点,拓扑排序的做法,好像没有上述面向数据的问题。

    #include<bits/stdc++.h>
    const int N=1e5+5;
    using namespace std;
    int n,m,k,s,t;
    struct edge{
    	int v,w;edge*s;
    }e[N*3];
    edge*b=e,*h[N];
    void add(int u,int v,int w){
    	edge s={v,w,h[u]};
    	*(h[u]=b++)=s;
    }
    int d[N],a[N],z[N],f[N];
    bool spfa(){
    	deque<int>q(1);
    	while(q.size()){
    		int u=q.front();
    		q.pop_front();
    		z[u]=0;
    		for(edge*i=h[u];i;i=i->s)
    			if(d[u]+i->w>d[i->v]){
    				d[i->v]=d[u]+i->w;
    				if(!z[i->v]++){
    					if(++a[i->v]==n)
    						return 0;
    					if(q.size()&&d[i->v]<d[q.front()])
    						q.push_back(i->v);
    					else
    						q.push_front(i->v);
    				}
    			}
    	}
    	return 1;
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	while(m--){
    		scanf("%d%d%d",&k,&s,&t);
    		if(k==1){
    			add(s,t,0);
    			add(t,s,0);
    		}
    		if(k==2){
    			if(s==t)return!~puts("-1");
    			add(s,t,1);
    		}
    		if(k==3)add(t,s,0);
    		if(k==4){
    			if(s==t)return!~puts("-1");
    			add(t,s,1);
    		}
    		if(k==5)add(s,t,0);
    	}
    	for(int i=1;i<=n;++i)
    		f[i]=i;
    	random_shuffle(f+1,f+n+1);
    	for(int i=1;i<=n;++i)
    		add(0,f[i],1);
    	printf("%lld
    ",!spfa()?-1:accumulate(d+1,d+n+1,0ll));
    }
    
  • 相关阅读:
    什么是序列化
    命令执行漏洞
    sql注入总结
    npm包之merge-descriptors
    Koa路由中间件之koa-router
    TypeScript声明文件(.d.ts)的使用
    TypeScript使用的简单记录
    TypeScript的安装、使用及配置
    Node websocket简单封装
    使用docker-compose配置mysql服务
  • 原文地址:https://www.cnblogs.com/f321dd/p/5721443.html
Copyright © 2011-2022 走看看