http://codeforces.com/contest/366
本题就是求一条路径,使得该路径上所有区间的公共子区间最大,输出最大值。
直接枚举该区间,再用DFS去判断使用这个区间的时候能不能从1节点走到n节点。
对于区间的左端点直接暴力枚举,枚举每一个出现过的左端点,对于右端点,采用二分枚举就可以了。
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define inf 2147480000
int n,m;
int v[10001];
int next[10001];
int head[10001];
int r[10001];
int l[10001];
int o;
int box[3001];
int maxn;
bool pig[1001];
bool dfs(int a,int l1,int r1)
{
if(a==n) return true;
if(l1>r1) return false;
for(int p=head[a];p>0;p=next[p])
{
if(!pig[v[p]])
{
if(l[p]<=l1 && r[p]>=r1)
{
pig[v[p]]=1;
if(dfs(v[p],l1,r1))
return true;
}
}
}
return false;
}
int main(int argc, char *argv[])
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int a,b,c,d;
cin>>a>>b>>c>>d;
o++;v[o]=b;next[o]=head[a];head[a]=o;l[o]=c;r[o]=d;
o++;v[o]=a;next[o]=head[b];head[b]=o;l[o]=c;r[o]=d;
box[i]=c;
maxn=max(maxn,d);
}
sort(box+1,box+1+m);
int now=-1;
int best=-1;
for(int i=1;i<=m;i++)
{
if(now!=box[i])
{
now=box[i];
int final=-1;
int ll=now;int rr=maxn;
while(ll<=rr)
{
int mid=(ll+rr)/2;
memset(pig,0,sizeof(pig));
pig[1]=1;
if(dfs(1,now,mid))
{final=mid;ll=mid+1;}
else
rr=mid-1;
}
if(final>=now)
best=max(best,final-now+1);
}
}
if(best!=-1)
cout<<best<<endl;
else cout<<"Nice work, Dima!"<<endl;
return 0;
}