AtCoder Beginner Contest 191.E - Come Back Quickly

该博客介绍了如何解决一个图论问题,即在给定的一组有向道路中找到从每个城镇出发能回到起点的最短时间路径。作者通过DFS实现,并应用了剪枝策略来优化时间复杂度。博客包含样例输入和输出,展示了算法的正确性和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

E - Come Back Quickly
Time Limit: 3 sec / Memory Limit: 1024 MB

Problem Statement
ln the Republic of AtCoder, there are N towns numbered 1 through N and M roads numbered 1 through M.
Road is a one-way roadfrom Town A; to Town B, and it takes Cyminutes to gothrough.it is possible that A = B, and there may be multple roadsconnecting the same pair of towns.

Takahashis thinking about taking a walkin the country. Wle will alla walk valid whenit goesthorough one or more roads and returns to the townitstarts at.Foreach town, determine whether there is a vald walk that starts atthat town.Additional if the answer is yes find the mininmun time such a walkrequires

Constraints
. 1<N<2000. 1<M ≤2000。 1< Ai<N. 1< B;≤N。 1<C≤105

All values in input are integers.
Input
Input is given from Standard Input in the following format:

Output

Print N lines.The i-th line (1 ≤i≤ N ) should contain the following:
if there is a valid walk that starts at Town i, the minimum time required by such a walk;. otherwise,-1.

Sample Input 1

4 4
1 2 5
2 3 10
3 1 15
4 3 20

Sample Output 1

30
30
30
-1

By Roads 1,2,3,Towns 1,2,3 forms a ring that takes 30 minutes to go around.From Town 4, we can go to Towns 1,2,3, but then we cannot return to Town 4.

Sample Input 2

4 6
1 2 5
1 3 10
2 4 5
3 4 10
4 1 10
1 1 10
Sample Output 2
10
20
30
20
There may be a road such that A;= B;.
Here, we can use just Road 6 to depart from Town 1 and return to that town.

Sample Input 3
Copy
4 7
1 2 10
2 3 30
1 4 15
3 4 25
3 4 20
4 3 20
4 3 30
Sample Output 3
Copy
-1
-1
40
40
Note that there may be multiple roads connecting the same pair of towns.

思路:虽说是全源最短路,但从时间复杂度来看floyd必然是不行的,所以写了个dfs,然后简单的写了两个剪枝,然后就过了

心得:手速太慢的,差一秒就上去就过了,提高代码从提高手速做起!!!

#include <bits/stdc++.h>
#define inf 0x7fffffff
//#define ll long long
#define int long long
//#define double long double
#define eps 1e-8
//#define mod 1e9+7
using namespace std;
const int mod=1e9+7;
const int M=1e5;
const int N=2*1e3+5;//空间最大限制 4e8
struct node
{
	int ver,next,edge;
}e[N];
int tot,head[N];
int d[N][N],v[N];
int n,m;
int ans,flag;
void add(int x,int y,int z)
{
	e[++tot].ver=y;
	e[tot].edge=z;
	e[tot].next=head[x];
	head[x]=tot;
}
void dfs(int x,int root,int sum)
{
	if(flag&&x==root)
	{
		ans=min(ans,sum);
		return;
	}
	if(flag&&sum>v[x])  return;//剪枝1
	if(sum>=ans)  return;//剪枝2
	flag=1;
	for(int i=head[x];i;i=e[i].next)
	{
		int y=e[i].ver;
		int z=e[i].edge;
		v[y]=min(v[y],v[x]+z);
		dfs(y,root,sum+z);
	}
}
signed main()
{
//	ios::sync_with_stdio(false);
	cin>>n>>m;
//	for(int i=0;i<=n+1;i++)  for(int j=0;j<=m+1;j++)  d[i][j]=1e12;
	for(int i=1;i<=m;i++)
	{
		int x,y,z;
		scanf("%lld%lld%lld",&x,&y,&z);
		add(x,y,z);
	}
	for(int i=1;i<=n;i++)
	{
		ans=1e12;
		flag=0;
		memset(v,0x3f,sizeof(v));
		v[i]=0;
		dfs(i,i,0);
		if(ans>=1e12)  printf("-1\n");
		else  printf("%lld\n",ans);
	}
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值