美团这个卖外卖的还考这些~~长见识!
题目描述
给定一个n个点m条无向边的连通图,每条边长度均为1
现在要求你删除尽量多的边,使得从s1到t1的最短路径不超过l1,并且s2到t2的最短路径不超过l2。
如果没有满足条件的方案,输出-1。
输入格式
第一行输入两个正整数n,m表示无向图的点数和边数。
接下来m行每行两个整数a,b表示节点a和节点b之间有一条边(点从1开始编号)。
接下来一行三个整数s1,t1,l1。
接下来一行三个整数s2,t2,l2。
1<=si,ti<=n
0<=li<=n
输入数据保证图连通并且没有重边和自环。
输出格式
输出一行一个整数,表示最多能够删多少条边,如果没有合法方案输出-1。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<vector>
#include<queue>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=1e5+10,INF=0x3f3f3f;
int n,a[N],b[N];
struct Edge{
int from,to,val,next,jud;
Edge(int from=-1,int to=-1,int val=0,int next=-1,int jud=-1):from(from),to(to),val(val),next(next),jud(jud){}
}e[N*2];
int len=0,last[N];
void add(int from,int to,int val,int jud) {
e[++len]=Edge(from,to,val,last[from],jud); last[from]=len;
}
void build_Graph() {
int w=-n+1;
for (int i=0;i<n;i++) {
if(i+a[i]>=0&&i+a[i]<n) add(i,i+a[i],w,1);
w++;
if(i+b[i]>=0&&i+b[i]<n) add(i,i+b[i],-w+1,0);
}
}
int inq[N],dis[N],vis[N];
struct road{
int id,node;
}pre[N];
int SPFA(int s) {
memset(inq,0,sizeof(inq));
memset(vis,0,sizeof(vis));
fo(i,0,n-1) {dis[i]=INF;pre[i].node=-1;}
fo(i,0,n-1) dis[i]=INF;
queue<int>q;
dis[s]=0;
q.push(s); inq[s]=1;
vis[s]++;
while(!q.empty()) {
int cur=q.front();
vis[cur]++;
if(vis[cur]>=n) return 0;
q.pop();
inq[cur]=0;
for(int i=last[cur];i;i=e[i].next) {
int id=e[i].to;
if(dis[id]>dis[cur]+e[i].val) {
dis[id]=dis[cur]+e[i].val;
pre[id].id=e[i].jud;
pre[id].node=cur;
if(!inq[id]) {
q.push(id);
inq[id]=1;
}
}
}
}
return 1;
}
//bool SPFA(int s){
// int num[MAXN];
// fo(i,1,n) dis[i]=1e5;
// memset(vis,0,sizeof(vis));
// memset(num,0,sizeof(num));
// queue<int> q;
// dis[s]=0;q.push(s);vis[s]=1;
// while(!q.empty()){
// int cur=q.front();
// q.pop();
// vis[cur]=0;
// num[cur]++;
// if(num[cur]>n) return 0;
// for(int i=last[cur];i;i=e[i].next)
// {
// int id=e[i].to;
// if(dis[id]>dis[cur]+e[i].val)
// {
// dis[id]=dis[cur]+e[i].val;
// if(!vis[id]){
// q.push(id);
// vis[id]=1;
// }
// }
// }
// }
// return -1;
//}
int main() {
scanf("%d",&n);
fo(i,0,n-1) scanf("%d",&a[i]);
fo(i,0,n-1) scanf("%d",&b[i]);
build_Graph();
// SPFA(0);
// printf("%d",dis[6]);
// fo(i,1,len) {
// printf("e[%d].from=%d .to=%d .val=%d .next=%d .jud=%d\n",i,e[i].from,e[i].to,e[i].val,e[i].next,e[i].jud);
// }
if(!SPFA(0)) {
printf("Infinity!\n");
}
else {
if(dis[n-1]==INF) printf("No solution!\n");
else {
int x=n-1;
int ans[N],cnt=0;
while(x!=0) {
ans[++cnt]=pre[x].id;
x=pre[x].node;
}
char key[N],tot=0;
fo(i,1,cnt) {
if(ans[i]) key[++tot]='a';
else key[++tot]='b';
}
for(int i=tot;i>=1;i--) {
printf("%c",key[i]);
}
cout<<endl;
}
}
return 0;
}