【暴力】开心小屋(smile)

D e s c r i p t i o n Description Description

Kc来到开心小屋。开心小屋是用来提升心情的。在这个小屋中有n个房间,一些房间之间有门连通。从房间i到达房间j,心情值可以加上-10000<=Cij<=10000,当然Cij可能是负的。现在kc失恋了,所以他想要知道他是否可以在这个小屋中无限地增加他的心情值,也就是无限地绕着一个环走?

请帮kc求出最小的环需要经过的房间数,来使他的心情无限增加。

I n p u t Input Input

第一行给出,1<=n<=300,1<=m<=5000。分别表示房间数及门的数量。

接下来m行,每行四个数:i,j,Cij,Cji

O u t p u t Output Output

输出文件包括一行,及最小的环需要经过的房间数。

保证不会出现自环及重边。

S a m p l e Sample Sample I n p u t Input Input
4 4
1 2 -10 3
1 3 1 -10
2 4 -10 -1
3 4 0 -3
S a m p l e Sample Sample O u t p u t Output Output
4

H i n t Hint Hint

1—>3—>4–>2–>1为最小的符合题意的环长度为4.
对30%的数据,n<=10;
对60%的数据,,n<=100;
对100%的数据,n<=300;

T r a i n Train Train o f of of T h o u g h t Thought Thought

暴力+剪枝
要找到环,就需要从 k k k点出发再走回 k k k
所以我们可以从 k k k点出发的时候,不把 k k k点标记

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;

int A[305][305], B[305];
int Ans, n, m, x, y;

void Dfs(int now, int Sum, int l, int k)
{
    
    
	if(Sum > Ans || l < 0)return;//当心情小于0可以直接退出
	if(now == k && Sum > 0)
	{
    
    
		if(l > 0)Ans = min(Ans, Sum);
		return;
	}
	for(int i = 1; i <= n; ++i)
		if(!B[i] && A[now][i] < 10000)
		{
    
    
			B[i] = 1;
			Dfs(i, Sum + 1, l + A[now][i], k);
			B[i] = 0;
		}
		return;
}

int main()
{
    
    
	scanf("%d%d", &n, &m);
	memset(A, 0x3f, sizeof(A));
	for(int i = 1; i <= m; ++i)
	{
    
    
		scanf("%d%d", &x, &y);
		scanf("%d%d", &A[x][y], &A[y][x]);
	}
	Ans = 1e9;
	for(int i = 1; i <= n; ++i)
		Dfs(i, 0, 0, i);
	printf("%d", Ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/SSL_wujiajie/article/details/108108857