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

    题目描述

    Farmer John has decided to assemble a panoramic photo of a lineup of his N cows (1 <= N <= 200,000), which, as always, are conveniently numbered from 1..N. Accordingly, he snapped M (1 <= M <= 100,000) photos, each covering a contiguous range of cows: photo i contains cows a_i through b_i inclusive. The photos collectively may not necessarily cover every single cow.

    After taking his photos, FJ notices a very interesting phenomenon: each photo he took contains exactly one cow with spots! FJ was aware that he had some number of spotted cows in his herd, but he had never actually counted them. Based on his photos, please determine the maximum possible number of spotted cows that could exist in his herd. Output -1 if there is no possible assignment of spots to cows consistent with FJ's photographic results.

    农夫约翰决定给站在一条线上的N(1 <= N <= 200,000)头奶牛制作一张全家福照片,N头奶牛编号1到N。

    于是约翰拍摄了M(1 <= M <= 100,000)张照片,每张照片都覆盖了连续一段奶牛:第i张照片中包含了编号a_i 到 b_i的奶牛。但是这些照片不一定把每一只奶牛都拍了进去。

    在拍完照片后,约翰发现了一个有趣的事情:每张照片中都有且仅有一只身上带有斑点的奶牛。约翰意识到他的牛群中有一些斑点奶牛,但他从来没有统计过它们的数量。 根据照片,请你帮约翰估算在他的牛群中最多可能有多少只斑点奶牛。如果无解,输出“-1”。

    Input

    输入输出格式

    输入格式:

    • Line 1: Two integers N and M.

    • Lines 2..M+1: Line i+1 contains a_i and b_i.

    输出格式:

    • Line 1: The maximum possible number of spotted cows on FJ's farm, or -1 if there is no possible solution.

    输入输出样例

    输入样例#1:

    5 3
    1 4
    2 5
    3 4

    输出样例#1:

    1

    说明

    There are 5 cows and 3 photos. The first photo contains cows 1 through 4, etc.

    From the last photo, we know that either cow 3 or cow 4 must be spotted. By choosing either of these, we satisfy the first two photos as well.


    差分约束系统

    可以处理不等式组的问题

    如果要求最大答案 :

    如果不等式可以化成 x[a] <= x[b] + delta

    那么就可以从 a -> b连 边权为 delta

    然后跑最小值

    如果要求最小答案 :

    如果不等式可以化成 x[a] >= x[b] + delta

    那么就可以从 a -> b 连 边权为 delta

    然后跑最大值

    注意图可能会不连通

    所以有时候要设置虚点0

    对于本题

    (d[v] - d[u - 1] <= 1)
    (d[v] <= d[u - 1] + 1)
    (d[v] - d[u - 1] >= 1)
    (d[u - 1] >= d[v] - 1)

    (d[i] - d[i - 1] <= 1)
    (d[i] - d[i - 1] >= 0)

    但是好像正解是dp

    然后出题人卡差分约束

    所以需要一些乱搞技巧卡常

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    const int M = 200055 ;
    using namespace std ;
    inline int read() {
    	char c = getchar() ; int x = 0 , w = 1 ;
    	while(c>'9'||c<'0') { if(c=='-') w = -1 ; c = getchar() ; }
    	while(c>='0'&&c<='9') { x = x*10+c-'0' ; c = getchar() ; }
    	return x*w ;
    }
    
    int n , m ;
    int hea[M] , num ;
    int dis[M] , cnt ;
    bool exist[M] ;
    struct Node { int id , v ; };
    priority_queue < Node > q ;
    struct E { int Nxt , to , Dis ; } edge[M << 2] ;
    inline bool operator < (Node a , Node b) 
    { return a.v > b.v ; }
    void add_edge(int from , int to , int dis) {
        edge[++num].Nxt = hea[from] ; edge[num].to = to ;
        edge[num].Dis = dis ; hea[from] = num ;
    }
    inline bool spfa() {
    	memset(exist , false , sizeof(exist)) ; exist[0] = true ;
    	memset(dis , 63 , sizeof(dis)) ; dis[0] = 0 ; q.push((Node) { 0 , 0 }) ;
    	while(!q.empty()) {
    		++cnt ; 
    		if(cnt > 1000000) return false ;
    		int u = q.top().id ; q.pop() ; exist[u] = false ;
    		for(int i = hea[u] ; i ; i = edge[i].Nxt) {
    			int v = edge[i].to ;
    			if(dis[v] > dis[u] + edge[i].Dis) {
    				dis[v] = dis[u] + edge[i].Dis ;
    				if(!exist[v]) {
    					exist[v] = true ;
    					q.push((Node) { v , dis[v] }) ;
    				}
    			}
    		}
    	}
    	return true ;
    }
    int main() {
    	n = read() ; m = read() ;
    	for(int i = 1 , u , v ; i <= m ; i ++) {
    		u = read() , v = read() ;
    		add_edge(u - 1 , v , 1) ; add_edge(v , u - 1 , -1) ;
    	}
    	for(int i = 1 ; i <= n ; i ++) {
    		add_edge(i - 1 , i , 1) ; 
    		add_edge(i , i - 1 , 0) ;
    	}
        if(spfa()) printf("%d
    ",dis[n]) ;
    	else printf("-1
    ") ;
    	return 0 ;
    }
    
  • 相关阅读:
    mysql去重
    java 实现一套流程管理、流转的思路(伪工作流)
    js模块加载框架 sea.js学习笔记
    使用js命名空间进行模块式开发
    二叉树的基本操作实现(数据结构实验)
    学生信息管理系统-顺序表&&链表(数据结构第一次作业)
    计算表达式的值--顺序栈(数据结构第二次实验)
    使用seek()方法报错:“io.UnsupportedOperation: can't do nonzero cur-relative seeks”错误的原因
    seek()方法的使用
    python中如何打印某月日历
  • 原文地址:https://www.cnblogs.com/beretty/p/9769308.html
Copyright © 2011-2022 走看看