车站分级,洛谷之提高历练地,较复杂图论I

正题

      其实你可以把它理解成一道差分约束的题目。

      第四题:车站分级

      很明显啊。车经过且不停靠的点一定比经过且停靠的点编号小。所以建立不等式xi-yj>=1(x是停靠车站,y是经过不停靠车站)。编号肯定相差1以上。又因为每个点的编号至少为1,所以从i-0>=1,我们从yj到xi建一条权值为一的边,从0向每一个车站建一条权值为1的边,做一便最长路即可。

代码<卡差分约束??我卡时你还能怎样>

#include
#include
#include
#include
#include
using namespace std;

int n,m;
int h[1010];
int s[1010][1010];
int len=0;
int first[1010];
bool tf[1010];
int p[1010];
deque f;
int mmax=0;
int kk[1010];
int t=0;

int SPFA(){
	f.push_back(0);
	fill(h,h+1+n,-1e9);
	h[0]=0;
	mmax=0;
	int temp=0;
	while(!f.empty()){
		int x=f.front();
		f.pop_front();
		tf[x]=false;
		for(int i=1;i<=n;i++){
			if(s[x][i]==0) continue;
			int y=i;
			if(h[y]=4000000) return mmax;
					tf[y]=true;
					if(!f.empty() && h[y]>h[f.front()])
						f.push_back(y);
					else 
						f.push_front(y);
				}
			}
		}
	}
	return mmax;
}

int main(){
	scanf("%d %d",&n,&m);
	int now;
	for(int i=1;i<=m;i++){
		int k;
		scanf("%d",&k);
		t=0;
		for(int j=1;j<=k;j++){
			scanf("%d",&p[j]);
			if(j!=1)
				for(int q=p[j-1]+1;q<=p[j]-1;q++)
					kk[++t]=q;
		}
		for(int j=1;j<=k;j++)
			for(int op=1;op<=t;op++)
				s[kk[op]][p[j]]=1;
	}
	for(int i=1;i<=n;i++)
		s[0][i]=1;
	printf("%d",SPFA());
}

你可能感兴趣的:(车站分级,洛谷之提高历练地,较复杂图论I)