poj 2983 差分约束
思路:
设dis[i]为标号为i的点到0号点的距离。对于P A B X,我们能得到等式dis[a]-dis[b]=x,那么可以化为两个不等式dis[a]-dis[b]>=x和dis[b]-dis[a]>=-x。这样就可以建两条边。V A B的话,我们知道dis[a]-dis[b]>=1,可以建一条边。这些边建起来后,图可能是一个离散的图,那么我们就定义一个超级源点连接所有的点,权值为0.进行求最长路时,只要判断是否有正圈存在,正圈的含义是绕着这个圈使每个点的dis值不断增大。用bellman-ford算法就行。还有一个笨的方法,其实是卡数据的,我们就用spfa求最长路,若循环次数超过一定,我们就认为有正圈存在。
这个是用bellman_ford做的:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define inf 1<<30
#define Maxn 10010
#define Maxm 500000
using namespace std;
int dis[Maxn],vi[Maxn],index[Maxn],e,Que[],num=,n;
struct Edge{
int to,next,val,from;
}edge[Maxm];
void init()
{
int i,j;
for( i=;i<=Maxn-;i++)
dis[i]=-inf;
memset(vi,,sizeof(vi));
memset(index,-,sizeof(index));
e=;
num=;
}
void addedge(int from,int to,int val)
{
edge[e].from=from;
edge[e].to=to;
edge[e].val=val;
edge[e].next=index[from];
index[from]=e++;
}
int bellman_ford()
{
int i,j,temp,flag;
for(i=;i<=n;i++)
{
flag=;
for(j=;j<e;j++)
{
temp=edge[j].from;
if(dis[temp]+edge[j].val>dis[edge[j].to])
{
dis[edge[j].to]=dis[temp]+edge[j].val;
flag=;
}
}
if(flag)
return ;
}
return ;
}
int main()
{
int i,j,a,b,c,m;
char str[];
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
//cout<<"ok"<<endl;
for(i=;i<=m;i++)
{
scanf("%s",&str);
if(str[]=='P')
{
scanf("%d%d%d",&a,&b,&c);
addedge(b,a,c);
addedge(a,b,-c);
}
else
{
scanf("%d%d",&a,&b);
addedge(b,a,);
}
}
for(i=;i<=n;i++)
addedge(,i,);
if(bellman_ford())
printf("Reliable\n");
else
printf("Unreliable\n");
}
return ;
}
给个卡数据的spfa:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define inf 1<<30
#define Maxn 10010
#define Maxm 500000
using namespace std;
int dis[Maxn],vi[Maxn],index[Maxn],e,Que[],num=;
struct Edge{
int to,next,val;
}edge[Maxm];
void init()
{
int i,j;
for( i=;i<=Maxn-;i++)
dis[i]=-inf;
memset(vi,,sizeof(vi));
memset(index,-,sizeof(index));
e=;
num=;
}
void addedge(int from,int to,int val)
{
edge[e].from=from;
edge[e].to=to;
edge[e].val=val;
edge[e].next=index[from];
index[from]=e++;
}
int spfa()
{
int i,j,temp,head,rear;
head=rear=;
Que[head++]=;
dis[]=;
//cout<<maxn<<endl;
while(head!=rear)
{
temp=Que[rear++];
//cout<<temp<<endl;
vi[temp]=;
for(i=index[temp];i!=-;i=edge[i].next)
{
int now=edge[i].to;
if(dis[now]<dis[temp]+edge[i].val)
{
num++;
if(num>)
return ;
if(edge[i].val<)
{
dis[temp]+edge[i].val+graphic[now][temp]
}
dis[now]=dis[temp]+edge[i].val;
if(!vi[now])
Que[head++]=now;
vi[now]=;
}
}
}
return ;
}
int main()
{
int i,j,n,a,b,c,m;
char str[];
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
//cout<<"ok"<<endl;
for(i=;i<=m;i++)
{
scanf("%s",&str);
if(str[]=='P')
{
scanf("%d%d%d",&a,&b,&c);
addedge(b,a,c);
addedge(a,b,-c);
}
else
{
scanf("%d%d",&a,&b);
addedge(b,a,);
}
}
for(i=;i<=n;i++)
addedge(,i,);
if(spfa())
printf("Reliable\n");
else
printf("Unreliable\n");
}
return ;
}
poj 2983 差分约束的更多相关文章
- poj 3159(差分约束经典题)
题目链接:http://poj.org/problem?id=3159思路:题目意思很简单,都与给定的条件dist[b]-dist[a]<=c,求dist[n]-dist[1]的最大值,显然这是 ...
- poj Layout 差分约束+SPFA
题目链接:http://poj.org/problem?id=3169 很好的差分约束入门题目,自己刚看时学呢 代码: #include<iostream> #include<cst ...
- poj 1201 差分约束
http://www.cnblogs.com/wangfang20/p/3196858.html 题意: 求集合Z中至少要包含多少个元素才能是每个区间[ai,bi]中的元素与Z中的元素重合个数为ci. ...
- POJ - 3169 差分约束
题意:n头牛,按照编号从左到右排列,两头牛可能在一起,接着有一些关系表示第a头牛与第b头牛相隔最多与最少的距离,最后求出第一头牛与最后一头牛的最大距离是多少,如 果最大距离无限大则输出 ...
- POJ 1201 差分约束+SPFA
思路: 差分约束,难在建图.(我是不会告诉你我刚学会SPFA的...) 把每个区间的ai–>bi连一条长度为ci的边. k–>k+1连一条长度为0的边. k+1–>k连一条长度为-1 ...
- POJ 1201 差分约束(集合最小元素个数)
题意: 给你一个集合,然后有如下输入,a ,b ,c表示在范围[a,b]里面有至少有c个元素,最后问你整个集合最少多少个元素. 思路: 和HDU1384一模一样,首先这个题目可 ...
- poj 1716 差分约束
水水的. 给几个不等式:dis[b]-dis[a]>=2; 0<=dis[i+1]-dis[i]<=1; #include<iostream> #include< ...
- poj 3159 差分约束
思路:班长的糖果要比snoopy的多.并且要用手写堆栈,且堆栈的大小要开到20000000. #include<iostream> #include<cstdio> #incl ...
- poj 1364 差分约束
思路:设dis[i]为从0点到第i点的序列总和.那么对于A B gt k 来讲意思是dis[B+A]-dis[A]>k; 对于A B lt k来讲就是dis[B+A]-dis[A]<k; ...
随机推荐
- No module named BeautifulSoup
遇到 No module named BeautifulSoup 错误,但是的确从官方下载了BeautifulSoup,并安装成功. 后来才发现,有两个BeautifulSoup的版本,一个是2012 ...
- BZOJ 2243: [SDOI2011]染色 (树链剖分+线段树合并)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2243 树链剖分的点剖分+线段树.漏了一个小地方,调了一下午...... 还是要细心啊! 结 ...
- POJ 2777 Count Color (线段树成段更新+二进制思维)
题目链接:http://poj.org/problem?id=2777 题意是有L个单位长的画板,T种颜色,O个操作.画板初始化为颜色1.操作C讲l到r单位之间的颜色变为c,操作P查询l到r单位之间的 ...
- C#全角半角转换函数
Code#region 全角半角转换 /// <summary> /// 转全角的函数(SBC case) /// </summary> /// <param name= ...
- opennebula 编译日志
[root@localhost opennebula-]# scons mysql=yes scons: Reading SConscript files ... Testing recipe: xm ...
- Centos 卸载OpenJdk
[root@localhost ~]# rpm -qa|grep jdkjava-1.6.0-openjdk-devel-1.6.0.0-1.50.1.11.5.el6_3.i686java-1.7. ...
- android知乎小圆圈刷新效果
前几天看到包括知乎在内的很多应用都使用到了一种小圆圈划动刷新的效果,仔细查了一下,原来是android v7包里面最新的刷新效果.使用起来也是十分简单的. 首先先建立一个activity,在布局文件里 ...
- win7硬盘安装Ubuntu12.04 64位时显示Error 15: File not found.
安装Ubuntu12.04 -64位时,用EasyBCD建好引导文件重启电脑后出现如下错误: Error 15: File not found 原因一个是安装文件所在盘符不对,另一个是文件名.Ubun ...
- 如何知道PostgreSQL数据库下每个数据库所对应的目录
base目录,这是所有数据库目录的父目录. 在base目录下第一层,每个目录就是一个数据库所对应的文件. 那么如何知道哪个目录对应哪个数据呢? 查询如下:先看数据库列表 [pgsql@localhos ...
- C++转义字符 & keyword
转义字符: 换行符 \n 水平制表符\t 纵向制表符 \v 退格符 \b 回车符 \r 进纸符 \f 报警(响铃)符 \a 反斜线 \\ 疑问号 \? 单引號 \' 双引號 \" ...