zoukankan      html  css  js  c++  java
  • [USACO13OPEN]照片Photo 题解

    题面

    这道题似乎可以用单调队列优化DP做,但这里讲的是一种差分约束的思路;

    设s[i]表示1~i中选了多少个;

    s[b[i]]-s[a[i]-1]<=1;

    s[b[i]]-s[a[i]-1]>=1;

    s[i]-s[i-1]<=1;

    s[i]-s[i-1]>=0;

    然后跑SPFA最短路;

    但要注意:普通的SPFA根本就过不去,所以我们应该使用双端队列优化的梦想SPFA

    #include <bits/stdc++.h>
    using namespace std;
    struct littlestar{
    	int to;
    	int nxt;
    	int w;
    }star[2000010];
    int head[2000010],cnt;
    void add(int u,int v,int w)
    {
    	star[++cnt].to=v;
    	star[cnt].nxt=head[u];
    	star[cnt].w=w;
    	head[u]=cnt;
    }
    int n,m;
    deque<int> q;
    int dis[1000010],vis[1000010];
    bool SPFA()
    {
    	for(register int i=1;i<=n;i++) dis[i]=999999999;
    	dis[0]=0;
    	vis[0]=1;
    	int tot=0;
    	q.push_back(0);
    	while(q.size()){
    		int u=q.front();
    		q.pop_front();
    		vis[u]=0;
    		for(register int i=head[u];i;i=star[i].nxt){
    			int v=star[i].to;
    			if(dis[v]>dis[u]+star[i].w){
    				dis[v]=dis[u]+star[i].w;
    				if(!vis[v]){
    					vis[v]=1;
    					++tot;
    					if(tot>2*(n+m)) return 0;
    					if(q.size()&&dis[v]>dis[q.front()]) q.push_back(v);
    					else q.push_front(v);
    				}
    			}
    		}
    	}
    	if(dis[n]==999999999) return 0;
    	return 1;
    }
    int main()
    {
    	cin>>n>>m;
    	for(register int i=1;i<=m;i++){
    		int u,v;
    		scanf("%d%d",&u,&v);
    		u--;
    		add(u,v,1);
    		add(v,u,-1);
    	}
    	for(register int i=1;i<=n;i++){
    		add(i-1,i,1);
    		add(i,i-1,0);
    	}
    	if(SPFA()) cout<<dis[n]<<" ";
    	else cout<<"-1";
    }
    
  • 相关阅读:
    poj 2000
    poj1316
    poj1922
    poj2017
    poj1833 排列
    poj1338
    poj2136
    poj2242
    IE兼容html5标签
    绑定事件后,某些情况下需要解绑该事件
  • 原文地址:https://www.cnblogs.com/kamimxr/p/11596300.html
Copyright © 2011-2022 走看看