洛谷P5683 [CSP-J2019 江西] 道路拆除

立下flag:今天一定AC这道题!

题目意思:

给你一个无向图,求从 1 到 s1 和 s2 的最短路径长度
不满足给定要求输出 -1

思路:

然而并没有分。。

输出-1,祈求CCF的施舍(

30% 的数据,有 \(s_1 = s_2\)

求 1 号点到 \(s_1\) 最短路,再计算不需要的路径。
SPFA,启动!

#include<bits/stdc++.h>

using namespace std;

const int maxn=3010;
const int maxm=3010;

int m,n;
int s1,t1,s2,t2;
int en;
int fir[maxn];

struct edge{
	int v;
	int next;
}ed[maxm*2];

void add_edge(int u,int v)
{
	en++;
	ed[en].v=v;
	ed[en].next=fir[u];
	fir[u]=en;
}

queue<int>q;
int dist[maxn];
bool inque[maxn];

void spfa(int r)
{
	memset(dist,0x3f3f3f,sizeof(dist));
	dist[r]=0;
	q.push(r);
	inque[r]=true;
	while(!q.empty())
	{
		int now=q.front();
		q.pop();
		for(int i=fir[now];i;i=ed[i].next)
		{
			int p=ed[i].v;
			if(dist[p]>dist[now]+1){
				dist[p]=dist[now]+1;
				if(inque[p]==false){
					inque[p]=true;
					q.push(p);
				}
			}
		}
	}
}

int main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		int u,v;
		cin>>u>>v;
		add_edge(u,v);add_edge(v,u);//无向图 
	 }
	cin>>s1>>t1>>s2>>t2;
	spfa(1);
	cout<<m-dist[s1]<<endl;
	return 0; 
}

居然多了5分,35分直接拿下!

正解( ?)

发现最佳情况一定是这样(如图)

\(a+b+c\) 的值最小的时候,方案是最优的,此时答案就是 \(m-(a+b+c)\)
那么我们就要找出这个 n
先算出 1、s1、s2这三个点分别到其余点的最短路,然后枚举 i 寻找最小值。
一定要把inque数组清零!!!!

#include<bits/stdc++.h>

using namespace std;

#define int long long

const int maxn=3010;
const int maxm=3010;
int ans=LLONG_MAX;

int m,n;
int s1,t1,s2,t2;
int en;
int fir[maxn];

struct edge{
	int v;
	int next;
}ed[maxm*2];

void add_edge(int u,int v)
{
	en++;
	ed[en].v=v;
	ed[en].next=fir[u];
	fir[u]=en;
}

queue<int>q;
int dist[4][maxn];
bool inque[maxn];

void spfa(int w,int r)
{
	for(int i=1;i<=n;i++)
	{
		dist[w][i]=0x3f3f3f;
	}
	memset(inque,false,sizeof(inque));
	dist[w][r]=0;
	q.push(r);
	inque[r]=true;
	while(!q.empty())
	{
		int now=q.front();
		q.pop();
		for(int i=fir[now];i;i=ed[i].next)
		{
			int p=ed[i].v;
			if(dist[w][p]>dist[w][now]+1){
				dist[w][p]=dist[w][now]+1;
				if(inque[p]==false){
					inque[p]=true;
					q.push(p);
				}
			}
		}
	}
}

signed main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		int u,v;
		cin>>u>>v;
		add_edge(u,v);add_edge(v,u);//无向图 
	 }
	cin>>s1>>t1>>s2>>t2;
	spfa(1,1);
	spfa(2,s1);
	spfa(3,s2);
	for(int i=1;i<=n;i++)
	{
		if(dist[1][i]+dist[2][i]<=t1&&dist[1][i]+dist[3][i]<=t2)
			ans=min(ans,dist[1][i]+dist[2][i]+dist[3][i]);
	}
	if(ans==LLONG_MAX) cout<<-1<<endl;
	else cout<<m-ans<<endl;
	return 0; 
}

简单捏~

艰辛AC路,一定是脑子抽了(确信

完结撒花!!!

posted @ 2024-09-22 16:20  lazy_ZJY  阅读(27)  评论(0编辑  收藏  举报