poj 1716 Integer Intervals
因为没提无解,就当是保证有解吧。为了方便,先把点的标号都加一。约束条件有三个。
(1)题目对区间的要求用前缀和表示 S[b+1]-s[a]>=2
(2)前缀和本身隐含一个约束条件 S[i]-S[i-1]>=0
(3)一个数字只取一次 S[i]-S[i-1]<=1
因为我想用SPFA求最短路,所以把不等式全部变形为 S[x]-S[y]<=C 的形式,从y向x连一条边权为C的边。输出那段随便写的,还没想,为什么(dis[maxn]-dis[0])和(dis[t]-dis[s])之间有矛盾。
一点关于差分约束的想法,首先要确定使用求最长路还是最短路算法,如果用最短路算法,松弛操作对于边(v,u)有dis[u]=min(dis[u],dis[v]+w),所以算法结束后一点有dis[u]<=dis[v]+w,即dis[u]-dis[v]<=w。就是说求其他点到其实点满足约束条件最小值,应该把约束条件写成<=形式,求最短路。求指正。
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
Code
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <vector>
using namespace std;
const int s=10000+1,t=0,n=10000;
int dis[n+10];
bool InQ[n+10];
vector<int> G[n+10];
queue <int> Q;
int main()
{
int m;
while(cin>>m){
if(m==0)break;
for(int i=0;i<=t;i++)G[i].clear();
for(int i=0;i<m;i++){
int a,b;
cin>>a>>b;
G[b+1].push_back(a);
}
memset(dis,127,sizeof(dis));
memset(InQ,0 ,sizeof(InQ));
Q.push(s);dis[s]=0;InQ[s]=0;
while(!Q.empty()){
int u=Q.front();Q.pop();
vector<int>::iterator i;
for(i=G[u].begin();i!=G[u].end();i++)
if(dis[*i]>dis[u]-2){
dis[*i]=dis[u]-2;
if(!InQ[*i]){
InQ[*i]=1;
Q.push(*i);
}
}
//i->i+1 1
if((u+1<=s)&&(dis[u+1]>dis[u]+1)){
dis[u+1]=dis[u]+1;
if(!InQ[u+1]){
InQ[u+1]=1;
Q.push(u+1);
}
}
//i->i-1 0
if((u-1>=t)&&(dis[u-1]>dis[u])){
dis[u-1]=dis[u];
if(!InQ[u-1]){
InQ[u-1]=1;
Q.push(u-1);
}
}
InQ[u]=0;
}
cout<<abs(dis[s]-dis[t])<<endl;
}
return 0;
}
poj 1201 Intervals
贴代码
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
Code
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <vector>
#define PII make_pair
using namespace std;
const int s=50000+1,t=0,n=50000;
int dis[n+10];
bool InQ[n+10];
typedef pair<int,int> edge;
vector<edge> G[n+10];
queue <int> Q;
int main()
{
int m;
while(cin>>m){
if(m==0)break;
for(int i=0;i<=t;i++)G[i].clear();
for(int i=0;i<m;i++){
int a,b,c;
cin>>a>>b>>c;
//s[b+1]-s[a]>=ci
//s[a]-s[b+1]<=-ci
//build (b+1)->a w=(-ci)
G[b+1].push_back(PII(a,-c));
}
memset(dis,127,sizeof(dis));
memset(InQ,0 ,sizeof(InQ));
Q.push(s);dis[s]=0;InQ[s]=0;
while(!Q.empty()){
int u=Q.front();Q.pop();
vector<edge>::iterator i;
for(i=G[u].begin();i!=G[u].end();i++){
int v=i->first,w=i->second;
if(dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
if(!InQ[v]){
InQ[v]=1;
Q.push(v);
}
}
}
//i->i+1 1
if((u+1<=s)&&(dis[u+1]>dis[u]+1)){
dis[u+1]=dis[u]+1;
if(!InQ[u+1]){
InQ[u+1]=1;
Q.push(u+1);
}
}
//i->i-1 0
if((u-1>=t)&&(dis[u-1]>dis[u])){
dis[u-1]=dis[u];
if(!InQ[u-1]){
InQ[u-1]=1;
Q.push(u-1);
}
}
InQ[u]=0;
}
cout<<abs(dis[0])<<endl;
}
return 0;
}