码迷,mamicode.com
首页 > 其他好文 > 详细

题解 CF543B 【Destroying Roads】

时间:2020-11-13 13:06:02      阅读:7      评论:0      收藏:0      [点我收藏+]

标签:保留   一点   删掉   ||   getc   cpp   lang   cstring   ==   

删掉更多的边则意味着保留的边肯定要尽量的少一点,那么我们可以把问题转化为求一个图中两条最短路中的最小值。

要先预处理出所有的点之间的最短路,并且将答案初始为 \(s_1\)\(t_1\)\(s_2\)\(t_2\) 的距离之和,此时不要忘了判断。

显然,我们所求的两条最短路中可能会有重合的部分,此时我们可以 \(n^2\) 枚举点对,来将路径分为5段进行处理,我们令中间的划分点为 i,j ,此时得到了5段路径,这时我们可以发现有两种情况:

  • \(s_1 \rightarrow i\)\(i \rightarrow j\)\(j \rightarrow t_1\)\(s_2 \rightarrow i\)\(j \rightarrow t_2\)

  • \(s_1 \rightarrow j\)\(j \rightarrow i\)\(i \rightarrow t_1\)\(s_2 \rightarrow i\)\(j \rightarrow t_2\)

求保留的边的最小值即可。

代码

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<cstring>
#define F1(i,l,r) for(int i=l;i<=r;++i)
#define F2(i,r,l) for(int i=r;i>=l;--i)
#define sf(i) scanf("%d",&i)
#define pf(i) printf("%d\n",i)
#define v e[i].to
#define inf 0x3f3f3f3f
#define N 3070
using namespace std;

inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (!isdigit(ch)){if (ch==‘-‘) f=-1;ch=getchar();}
	while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return x*f;
}

struct Edge{
	int to,nxt,w;
}e[N*N];
int n,m,s1,t1,l1,s2,t2,l2,cnt;
int d[N][N],head[N];
bool vis[N][N];

void add(int from,int to,int val){
	e[++cnt].to=to;
	e[cnt].w=val;
	e[cnt].nxt=head[from];
	head[from]=cnt;
}

void Spfa(int s){
	for(int i=1;i<=n;++i) vis[s][i]=0;
	d[s][s]=0;
	queue<int>q;
	q.push(s);
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=head[u];i;i=e[i].nxt)
			if(v!=s&&d[s][v]>d[s][u]+e[i].w){
				d[s][v]=d[s][u]+e[i].w;
				if(!vis[s][v]){
					vis[s][v]=1;
					q.push(v);
				}
			}
	}
}

int main(){
	sf(n),sf(m);
	memset(d,0x3f,sizeof(d));
	F1(i,1,m){int a,b;a=read(),b=read();add(a,b,1),add(b,a,1);}
	F1(i,1,n) Spfa(i);
	sf(s1),sf(t1),sf(l1),sf(s2),sf(t2),sf(l2);
	if(d[s1][t1]>l1||d[s2][t2]>l2){pf(-1);return 0;}
	int ans=d[s1][t1]+d[s2][t2];
	F1(i,1,n)
		F1(j,1,n){
			if(d[s1][i]+d[i][j]+d[j][t1]<=l1&&d[s2][i]+d[i][j]+d[j][t2]<=l2)
				ans=min(ans,d[s1][i]+d[i][j]+d[j][t1]+d[s2][i]+d[j][t2]);
			if(d[s1][j]+d[i][j]+d[i][t1]<=l1&&d[s2][i]+d[i][j]+d[j][t2]<=l2)
				ans=min(ans,d[s1][j]+d[i][j]+d[i][t1]+d[s2][i]+d[j][t2]);			
	}
	pf(m-ans);
}

呃呃,码风恶臭

题解 CF543B 【Destroying Roads】

标签:保留   一点   删掉   ||   getc   cpp   lang   cstring   ==   

原文地址:https://www.cnblogs.com/Niuwadiandian/p/13944724.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!