Mars OJ 1985破坏道路

说明

在某些国家,恰好有n个城市和m 个连接城市的双向道路。城市用从1到n的整数编号。如果城市a和b由一条道路连接,那么在一个小时内,您可以沿着这条道路从城市a到城市b,或者从城市b到城市a。道路网络是这样的,从任何一个城市你都可以沿着道路移动到任何另一个城市。

你想在乡间小路上摧毁最大可能的道路数量,使剩余的道路将允许您从城市s1到t1中最多用l1小时,从城市s2到城市t2最多用l2小时。

确定您需要破坏的最大道路数量。如果无法达到预期目标,则打印 -1。

输入格式

第一行包含两个整数n,m(1 ≤n≤ 3000,

) — 分别是国家的城市和道路数量。

接下来的m行包含对道路的描述,作为整数对ai,bi(1 ≤ai,bi≤n,ai≠bi)。保证描述中给出的道路可以将您从任何城市运送到任何其他城市。保证每对城市之间最多有一条道路。

最后两行分别包含三个整数s1,t1,l1和s2,t2,l2(1 ≤si,ti≤n,0 ≤li≤n)。

输出格式

一行一个整数表示答案,如果无法满足条件,输出-1

样例

输入数据 1

5 4
1 2
2 3
3 4
4 5
1 3 2
3 5 2

输出数据 1

0
C

 思路:用bfs求多源多汇最短路,用dis[u][v]表示,然后s1->t1,s2->t2最短路中间若是有重叠的线路,一定是连续的一段,于是枚举连续段的起点i和终点j, 最终答案从s1-i-j-t1+s2-i+j-t2中取min

个人犯的一个错:最后双重循环最内层要有两个if判断,s2可以到i也可以到j哦

(今天暂时没空,后面有时间补充说明)

代码:

#include<bits/stdc++.h>
#define MAXN 3010
#define MAXM 9000010

using namespace std;

struct tEdge{
	int u,v,nxt;
}g_e[MAXM];
int cnt=0,head[MAXN],dis[MAXN][MAXN];
bool vis[MAXN];
queue<int> g_q;

void addedge(int u, int v)
{
	g_e[++cnt].u=u,g_e[cnt].v=v;
	g_e[cnt].nxt=head[u],head[u]=cnt;
}
void bfs(int s)
{
	vis[s]=1;
	dis[s][s]=0;
	g_q.push(s);
	while(!g_q.empty())
	{
		int tmp=g_q.front();
		g_q.pop();
		for(int i=head[tmp];i;i=g_e[i].nxt)
		{
			int v=g_e[i].v;
			if(!vis[v])
			{
				dis[s][v]=dis[s][tmp]+1; 
				g_q.push(v);
				vis[v]=1;
			}
		}
	}
}

int main()
{
	memset(dis,0x3f,sizeof(dis));
	int n,m,a,b,s1,t1,l1,s2,t2,l2;
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;++i)
	{
		scanf("%d %d",&a,&b);
		addedge(a,b),addedge(b,a);
	}
	scanf("%d %d %d %d %d %d",&s1,&t1,&l1,&s2,&t2,&l2);
	for(int i=1;i<=n;++i)
	{
		g_q=queue<int>();
		memset(vis,0,sizeof(vis));
		bfs(i);
	}
//	for(int i=1;i<=n;++i)
//	{
//		for(int j=1;j<=n;++j)
//		{
//			cout<<dis[i][j]<<" "; 
//		}
//		cout<<endl;
//	}
	if(dis[s1][t1]>l1||dis[s2][t2]>l2)
	{
		printf("-1");
		return 0;
	}
	int ans=dis[s1][t1]+dis[s2][t2];
	for(int i=1;i<=n;++i)
	{
		for(int j=1;j<=n;++j)
		{
			if(dis[s1][i]+dis[i][j]+dis[j][t1]<=l1&&dis[s2][i]+dis[i][j]+dis[j][t2]<=l2)
				ans=min(ans,dis[s1][i]+dis[i][j]+dis[j][t1]+dis[s2][i]+dis[j][t2]);
			if(dis[s1][i]+dis[i][j]+dis[j][t1]<=l1&&dis[s2][j]+dis[i][j]+dis[i][t2]<=l2)
				ans=min(ans,dis[s1][i]+dis[i][j]+dis[j][t1]+dis[s2][j]+dis[i][t2]);
		}
	}
	printf("%d",m-ans);
	return 0;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值