• Week8 作业 A


    题目描述:

    给定一个数轴上的 n 个区间,要求在数轴上选取最少的点使得第 i 个区间 [ai, bi] 里至少有 ci 个点;

    输入输出规模及约定:

    输入第一行一个整数 n 表示区间的个数,接下来的 n 行,每一行两个用空格隔开的整数 a,b 表示区间的左右端点。

    1 <= n <= 50000, 0 <= ai <= bi <= 50000 并且1 <= ci <= bi - ai+1。

    输出一个整数表示最少选取的点的个数

    思路:

    关于差分约束系统:https://blog.csdn.net/my_sunshine26/article/details/72849441 ,这篇博文写的挺好,不再搬运了。

    如果我们用sum[i]表示在i及之前,选了多少了个点,则下述差分约束成立:

    sum[bi+1] - sum[a] >= ci

    0=<sum[i+1] - sum[i] <=1

    然后跑最长路,sum[ max{bi} ]就是结果;

    值得注意的点:

    1、用sum[b+1] - sum[a] 而不是 sum[b] - sum[a-1] ,因为我们图的顶点通常不用负值。相当于把数轴(所有区间)向右移了一个单位。最后求bi的max的时候,每个bi必须加1

    2、同理用sum[i+1] - sum[i] 而不是 sum[i] -sum[i-1] 

    3、存储边的数组要开的足够大,该结论可以通过仔细分析差分约束条件得出。

    代码:

    #include <cstdio>
    #include <iostream>
    #include <queue>
    #include <climits>	//防止出现负的下标,转换成sum[b+1]-sum[a]>=c 
    using namespace std;
    const int MAXN=5e4+5;
    struct e
    {
    	int v,w,next;
    }Edge[3*MAXN];		//值得注意的是边数 
    int last[MAXN];	//因为可能有零点,last数组要初始化成-1 
    int tot;
    int dis[MAXN],inq[MAXN];
    int maxb=-1;
    int mina=INT_MAX;
    void addEdge(int u,int v,int w)
    {
    	tot++;
    	Edge[tot].v=v;
    	Edge[tot].w=w;
    	Edge[tot].next=last[u];
    	last[u]=tot;
    }
    void SPFA()
    {
    	for(int i=mina;i<=maxb;i++)
    		dis[i]=-INT_MAX;
    	queue<int> q;
    	q.push(mina);
    	inq[mina]=1;
    	dis[mina]=0;
    	while(!q.empty())
    	{
    		int u=q.front();
    		q.pop();
    		inq[u]=0;
    		for(int i=last[u];i!=-1;i=Edge[i].next)
    		{
    			int v=Edge[i].v,w=Edge[i].w;
    			if(dis[v]<dis[u]+w)
    			{
    				dis[v]=dis[u]+w;
    				if(inq[v]==1) continue;
    				else inq[v]=1,q.push(v);
    			}
    		}
    	}
    }
    int main()
    {
    	int N; cin>>N;
    
    	for(int i=0;i<MAXN;i++)	last[i]=-1; 
    	for(int i=1;i<=N;i++)
    	{
    		int u,v,w;
    		scanf("%d %d %d",&u,&v,&w);
    		maxb=max(v+1,maxb);
    		mina=min(u,mina);
    		addEdge(u,v+1,w);   //(v)-(u-1)>=c 
    	}
    	for(int i=mina;i<=maxb;i++)
    	{
    		addEdge(i+1,i,-1);
    		addEdge(i,i+1,0); 
    	}
    	SPFA();
    	cout<<dis[maxb]<<endl;
    	return 0;
    }
    

      

  • 相关阅读:
    SecureCRT
    Jsoup 标签选择器 选择img标签中src的值
    使用Jsoup 爬取网易首页所有的图片
    java自定义类型 比较排序 Comparator接口
    eclipse下导入jdk源码
    java爬虫--使用正则表达式获取网页中的email
    Java正则表达式--Matcher.group函数的用法
    使用org.jsoup.Jsoup下载网络中的图片
    Tomcat中的Session小结
    关于JAVA中的static方法、并发问题以及JAVA运行时内存模型
  • 原文地址:https://www.cnblogs.com/qingoba/p/12720325.html
Copyright © 2020-2023  润新知