题目链接:https://cn.vjudge.net/contest/276233#problem/D

给出n个闭合的整数区间[ai,bi]和n个整数c1,…,cn。

编写一个程序:
从标准输入中读取间隔数,它们的端点和整数c1,…,cn,
计算具有间隔[ai,bi]的至少ci共同元素的整数集合Z的最小尺寸,对于每个i = 1,2,…,n,

具体思路:首先,我们假设存在一个数组s,s[i]记录的是第i个点到第0个点的需要取出的点的个数,对于题目中的从(A,B)至少有d个,我们就可以将这个条件变成posB-(posA-1)>=d,也就是(posA-1)-posB<=-d,这一段的边就建立好了,但是对于这个区间内的每一个数,我们的范围是没有限制的,但是如果没有限制会出现下列情况,s[i]>=i,也就是说会出现矛盾,所以对于这个区间内的没一个数都需要限制,也就是对于区间(i,i+1),我们可以引申出如下条件。0=<pos(i+1)-pos(i)<=1,

也就是 pos[i+1]-pos[i]>=0(pos[i]-pos[i+1]<=0),和 pos[i+1]-pos[i]<=1,也就是把这段区间的每一个小的区间的条件设立好了就可以了。(注意建边的时候注意方向)

AC代码:

 #include<bits/stdc++.h>
using namespace std;
# define ll long long
# define inf 0x3f3f3f3f
const int maxn = +;
const int maxedge= +;
int num,head[maxn];
int dis[maxn],vis[maxn];
int minx=inf;
int maxy=;
struct node
{
int fr;
int to;
int cost;
int nex;
} edge[maxedge];
struct point
{
int st;
int ed;
} po[maxn];
void init()
{
for(int i=; i<=; i++)
{
head[i]=-;
vis[i]=;
dis[i]=inf;
}
num=;
}
void addedge(int fr,int to,int cost)
{
edge[num].to=to;
edge[num].cost=cost;
edge[num].nex=head[fr];
head[fr]=num++;
}
ll spfa(int st,int ed)
{
dis[st]=;
vis[st]=;
queue<int>q;
q.push(st);
while(!q.empty())
{
int tmp=q.front();
q.pop();
vis[tmp]=;
for(int i=head[tmp]; i!=-; i=edge[i].nex)
{
int u=edge[i].to;
if(dis[u]>dis[tmp]+edge[i].cost)
{
dis[u]=dis[tmp]+edge[i].cost;
if(vis[u])
continue;
vis[u]=;
q.push(u);
}
}
}
return dis[ed];
}
int main()
{
int n,d;
scanf("%d",&n);
init();
for(int i=; i<=n; i++)
{
scanf("%d %d %d",&po[i].st,&po[i].ed,&d);
addedge(po[i].st-+,po[i].ed+,-d);//两个左边都+1,是为了防止出现变成-1的情况。
minx=min(minx,po[i].st);
maxy=max(maxy,po[i].ed+);
}
for(int i=minx; i<=maxy-; i++)
{
addedge(i,i+,);
addedge(i+,i,);
}
int ans=spfa(minx,maxy);
printf("%d\n",-ans);
return ;
}

E:

n个数的一个序列,m个约数,si, ni, oi, ki, 代表了序列中第si个数到第si+ni个数的和大于或小于ki,gt = 大于,lt = 小于

问是否存在相悖的约束

一个由memset引发的惨案,,,本来是用for循环初始化来着,结果这个题用for一直wa(后来发现是越界了--),然后改成memset的化就给过了。但是顺便加深了对建图的理解(理解写在上面了)。

AC代码:

   #include<bits/stdc++.h>
using namespace std;
# define ll long long
# define inf 0x3f3f3f3f
const int maxn = +;
const int maxedge= +;
int num,head[maxn],out[maxn];
int dis[maxn],vis[maxn];
int n,m;
struct node
{
int fr;
int to;
int cost;
int nex;
} edge[maxedge];
struct point
{
int st;
int ed;
} po[maxn];
void init()
{
for(int i=; i<maxn; i++)
{
vis[i]=;
dis[i]=inf;
head[i]=-;
out[i]=;
}
num=;
num=;
}
void addedge(int fr,int to,int cost)
{
edge[num].to=to;
edge[num].cost=cost;
edge[num].nex=head[fr];
head[fr]=num++;
}
ll spfa(int st)
{
dis[st]=;
vis[st]=;
queue<int>q;
q.push(st);
while(!q.empty())
{
int tmp=q.front();
q.pop();
if(++out[tmp]>n+)
return -;
vis[tmp]=;
for(int i=head[tmp]; i!=-; i=edge[i].nex)
{
int u=edge[i].to;
if(dis[u]>dis[tmp]+edge[i].cost)
{
dis[u]=dis[tmp]+edge[i].cost;
if(vis[u])
continue;
vis[u]=;
q.push(u);
}
}
}
return ;
}
int main()
{
while(cin>>n)
{
init();
if(n==)
break;
cin>>m;
int u,v,d;
string str;
for(int i=; i<=m; i++)
{
cin>>u>>v>>str>>d;
if(str=="gt")
{
addedge(u,u+v+,-(d+));
}
else
{
addedge(v+u+,u,d-);
}
}
for(int i=; i<=n+; i++)
{
addedge(,i,);//超级源点的建立过程
}
int ans=spfa();
if(ans==-)
cout<<"successful conspiracy"<<endl;
else
cout<<"lamentable kingdom"<<endl;
}
return ;
}

G题:

给出数轴上的n个闭合int型区间。现在要在数轴上任意取一堆元素,构成一个元素集合V,要求给出的每个区间和元素集合V的交集至少有两个不同的元素,求集合V最小的元素个数。

超级源点的建立,为了保证整个区间的连通的,我们就需要建立一个超级源点来使得整个图是连通的,但是注意一点,在正常建边的时候,如果是大的指向小的,这个时候我们建立超级源点的时候就也应该遵循这个原则,如果是是小的指向大的,我们建立超级源点的时候反过来就可以了。

AC代码:

   #include<bits/stdc++.h>
using namespace std;
# define ll long long
# define inf 0x3f3f3f3f
const int maxn = +;
const int maxnedge=+;
struct node
{
int nex;
int to;
int cost;
} edge[maxnedge];
int head[maxn],vis[maxn],dis[maxn],num;
void init()
{
memset(head,-,sizeof(head));
memset(vis,,sizeof(vis));
memset(dis,inf,sizeof(dis));
num=;
}
void addedge(int fr,int to,int cost)
{
edge[num].to=to;
edge[num].nex=head[fr];
edge[num].cost=cost;
head[fr]=num++;
}
int spfa(int st,int ed)
{
queue<int>q;
dis[st]=;
vis[st]=;
q.push(st);
while(!q.empty())
{
int tmp=q.front();
q.pop();
vis[tmp]=;
for(int i=head[tmp]; i!=-; i=edge[i].nex)
{
int u=edge[i].to;
if(dis[u]>dis[tmp]+edge[i].cost)
{
dis[u]=dis[tmp]+edge[i].cost;
if(vis[u])
continue;
vis[u]=;
q.push(u);
}
}
}
return dis[ed];
}
int main()
{
init();
int n;
scanf("%d",&n);
int u,v;
int minx=inf,maxy=;
for(int i=; i<=n; i++)
{
scanf("%d %d",&u,&v);
u+=;
v+=;
addedge(u-,v,-);
addedge(v,u-,v-u+);
minx=min(minx,u-);
maxy=max(maxy,v);
}
int st=maxy+;
for(int i=minx; i<maxy; i++){
addedge(st,i,);
addedge(i,i+,);
addedge(i+,i,);
}
addedge(st,maxy,);
int ans=spfa(st,maxy);
printf("%d\n",-ans);
return ;
}

spfa+差分约束系统(D - POJ - 1201 && E - POJ - 1364&&G - POJ - 1)+建边的注意事项+超级源点的建立的更多相关文章

  1. spfa+差分约束系统(C - House Man HDU - 3440 )+对差分约束系统的初步理解

    题目链接:https://cn.vjudge.net/contest/276233#problem/C 题目大意:有n层楼,给你每个楼的高度,和这个人单次的最大跳跃距离m,两个楼之间的距离最小是1,但 ...

  2. poj 1364 King(线性差分约束+超级源点+spfa判负环)

    King Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14791   Accepted: 5226 Description ...

  3. UVA 11374 Halum (差分约束系统,最短路)

    题意:给定一个带权有向图,每次你可以选择一个结点v 和整数d ,把所有以v为终点的边权值减少d,把所有以v为起点的边权值增加d,最后要让所有的边权值为正,且尽量大.若无解,输出结果.若可无限大,输出结 ...

  4. 差分约束系统专题 && 对差分约束系统的理解

    具体能解决的问题: 求最长路,最短路,或者判断解是否存在. 在建边的时候: 一般是给你区间减法的关系,或者是这个点到另一个点的关系.如果给你的关系是除法的话,我们可以通过使用两边同时取log的方式,将 ...

  5. 【POJ 1201】 Intervals(差分约束系统)

    [POJ 1201] Intervals(差分约束系统) 11 1716的升级版 把原本固定的边权改为不固定. Intervals Time Limit: 2000MS   Memory Limit: ...

  6. 差分约束系统 + spfa(A - Layout POJ - 3169)

    题目链接:https://cn.vjudge.net/contest/276233#problem/A 差分约束系统,假设当前有三个不等式 x- y <=t1 y-z<=t2 x-z< ...

  7. poj 1201 Intervals(差分约束)

    做的第一道差分约束的题目,思考了一天,终于把差分约束弄懂了O(∩_∩)O哈哈~ 题意(略坑):三元组{ai,bi,ci},表示区间[ai,bi]上至少要有ci个数字相同,其实就是说,在区间[0,500 ...

  8. POJ 3169 Layout (spfa+差分约束)

    题目链接:http://poj.org/problem?id=3169 差分约束的解释:http://www.cnblogs.com/void/archive/2011/08/26/2153928.h ...

  9. POJ 3159 Candies (图论,差分约束系统,最短路)

    POJ 3159 Candies (图论,差分约束系统,最短路) Description During the kindergarten days, flymouse was the monitor ...

随机推荐

  1. Art & Material

    Art(Android runtime)模式伴随Android 4.4发布.相对于Dalvik模式来说,Art模式改善了Android程序的性能. Material Design伴随Android 5 ...

  2. LinkedList,HashSet,HashMap

    LinkedList底层源码是采用双向链表实现的 private static class Node<E> { E item;//节点值 Node<E> next;//节点后指 ...

  3. delphi(假三层之数据访问层)(第一天)

    本论文主要是通过三天来讲解三层的结构,今天是第一天,先讲解一下delphi下的Models层,我主要封装了两个查询得到数据集的函数,主要是通过在表示层上创建的数数据集控件传递进来,通过业务逻辑对语句的 ...

  4. A Mist of Florescence CodeForces - 989C(思维构造)

    题意: 让你构造一个图,使得A,B,C,D的个数为给定的个数,上下左右连通的算一个. 哎呀 看看代码就懂了..emm..很好懂的 #include <bits/stdc++.h> usin ...

  5. Little Elephant and Array CodeForces - 220B(莫队)

    给一段长为n的序列和m个关于区间的询问,求出每个询问的区间中有多少种数字是 该种数字出现的次数等于该数字 的. #include <iostream> #include <cstdi ...

  6. vs2017自动生成的#include“stdafx.h”详解及解决方案

    vs2017自动生成的#include“stdafx.h”详解及解决方案 问题描述: 在高版本的Visual Studio的默认设置中,会出现这么一个现象,在新建项目之后,项目会自动生成#includ ...

  7. 【spring学习笔记一】Ioc控制反转

    (最近有点捞,在大一的时候还通过写博客的方式督促自己学习唉,先培养起习惯,再找个好点的地方重新开始写博客⑧) Spring是JAVA的一个框架. 有个概念叫依赖注入(或者还有个名字叫控制反转). 概念 ...

  8. 【UOJ228】基础数据结构练习题(线段树)

    [UOJ228]基础数据结构练习题(线段树) 题面 UOJ 题解 我们来看看怎么开根? 如果区间所有值都相等怎么办? 显然可以直接开根 如果\(max-sqrt(max)=min-sqrt(min)\ ...

  9. 使用mshta.exe绕过应用程序白名单(多种方法)

      0x00 简介 很长一段时间以来,HTA文件一直被web攻击或在野恶意软件下载程序用作恶意程序的一部分.HTA文件在网络安全领域内广为人知,从红队和蓝队的角度来看,它是绕过应用程序白名单有价值的“ ...

  10. linux内核分析 第七周 Linux内核如何装载和启动一个可执行程序

    一.编译链接的过程和ELF可执行文件格式 vi hello.c gcc -E -o hello.cpp hello.c -m32 //预处理.c文件,预处理包括把include的文件包含进来以及宏替换 ...