cogs 1685 魔法森林
/* 写了个傻逼二分套二分,真的傻逼了,我这tmd是在贪心呐,70分满满的人品 */ #include<iostream> #include<cstdio> #include<cstring> #include<queue> #define maxn 50010 using namespace std; int head[maxn],num,n,m,mx1,mx2,mid1,mid2,ans=0x7fffffff; bool vis[maxn],ok[100010]; struct node{int to,pre,v1,v2;}e[200010]; struct Node{int from,to,v1,v2;}edge[100010]; void Insert(int from,int to,int v1,int v2){ e[++num].to=to; e[num].v1=v1; e[num].v2=v2; e[num].pre=head[from]; head[from]=num; } void bfs(){ queue<int>q; q.push(1);vis[1]=1; while(!q.empty()){ int now=q.front();q.pop(); for(int i=head[now];i;i=e[i].pre){ int to=e[i].to; if(!vis[to]){vis[to]=1;q.push(to);} } } } bool check1(){ memset(vis,0,sizeof(vis)); memset(ok,0,sizeof(ok)); memset(head,0,sizeof(head));num=0; for(int i=1;i<=m;i++){ if(edge[i].v1>mid1)continue; Insert(edge[i].from,edge[i].to,edge[i].v1,edge[i].v2); Insert(edge[i].to,edge[i].from,edge[i].v1,edge[i].v2); ok[i]=1; } bfs(); return vis[n]; } bool check2(){ memset(vis,0,sizeof(vis)); memset(head,0,sizeof(head));num=0; for(int i=1;i<=m;i++){ if((edge[i].v2>mid2)||(!ok[i]))continue; Insert(edge[i].from,edge[i].to,edge[i].v1,edge[i].v2); Insert(edge[i].to,edge[i].from,edge[i].v1,edge[i].v2); } bfs(); return vis[n]; } int main(){ freopen("magicalforest11.in","r",stdin);//freopen("magicalforest.out","w",stdout); scanf("%d%d",&n,&m); int x,y,z,c; for(int i=1;i<=m;i++){ scanf("%d%d%d%d",&x,&y,&z,&c); edge[i].from=x;edge[i].to=y;edge[i].v1=z;edge[i].v2=c; Insert(x,y,z,c);Insert(y,x,z,c); mx1=max(mx1,z); mx2=max(mx2,c); } bfs(); if(!vis[n]){puts("-1");return 0;} int l1=1,r1=mx1; while(l1<=r1){ mid1=(l1+r1)>>1; if(check1()){ int l2=1,r2=mx2; while(l2<=r2){ mid2=(l2+r2)>>1; if(check2())r2=mid2-1,ans=min(ans,mid1+mid2); else l2=mid2+1; } r1=mid1-1; } else l1=mid1+1; } printf("%d",ans); return 0; }