社区讨论

关于我dij+A*,样例没过却AC那件事

P1078[NOIP 2012 普及组] 文化之旅(疑似错题)参与者 3已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@lrcajph7
此快照首次捕获于
2024/01/14 00:37
2 年前
此快照最后确认于
2024/01/14 11:06
2 年前
查看原帖
所以大佬们能帮忙看看我样例为啥没过咩?我没想明白为啥我第一个样例的结果是-1,我开了dij的剪枝就变成了10,不开剪枝反而变成了-1,不应该剪枝越少越有可能出答案吗? (就是sum+mp[now][i]<=tmp[t]的这个剪枝,我不开剪枝能过样例但是会TLE)
CPP
#include <bits/stdc++.h>
using namespace std;
int n,k,m,s,t,ans=0x3f3f3f3f,tmp[110],q[110]; 
int cul[110],okc[110][110],mp[110][110]; // okc[i][j]==1 : i号文明接受 j文明 
int ok[110],okcul[110],okk;  // ok[i] : i号节点走过了   okcul[i] : i 号文化已收集 
void dfs (int now,int sum)
{
//	cout<<now<<" "<<sum<<endl; 
	if (now==t) {
		ans=ans>sum?sum:ans;
		return ;
	}
	for (int i=1;i<=n;i++) {
//		cout<<i<<"!"<<endl;
		if (mp[now][i]!=0x3f3f3f3f && ok[i]==0 && sum+mp[now][i]<=ans && sum+mp[now][i]<=tmp[t]) {
//			cout<<"yes1"<<endl;
			okk=1;
			for (int j=1;j<=t;j++)
				if (okcul[j] && okc[cul[i]][j]==0) {
					okk=0;
					break;
				}
//			cout<<"yes2"<<endl;
			if (okk==1) {
				ok[i]=1;
				okcul[cul[i]]=1;
				dfs(i,sum+mp[now][i]);
				ok[i]=0;
				okcul[cul[i]]=0;
			}
		}
	}
}
void dij (int x,int d)
{
//	cout<<x<<" "<<d<<endl;
	if (x==t || okk==1) {
		okk=1;
		return ;
	}
	int mini=0,mins=0x3f3f3f3f;
	for (int i=1;i<=d;i++) {
		for (int j=1;j<=n;j++)
			if (mp[j][q[i]]!=0x3f3f3f3f && j!=q[i] && tmp[j]==0) {
//				cout<<j<<endl;
				if (mins>tmp[q[i]]+mp[j][q[i]]) {
					mins=tmp[q[i]]+mp[j][q[i]];
					mini=j;
				}
			}
	}
//	cout<<mini<<" "<<mins<<endl;
	tmp[mini]=mins;
	q[++d]=mini;
	dij(mini,d);
}
int main()
{
	scanf("%d%d%d%d%d",&n,&k,&m,&s,&t);
	for (int i=1;i<=n;i++)
		scanf("%d",&cul[i]);
	for (int i=1;i<=k;i++)
		for (int j=1;j<=k;j++) {
			scanf("%d",&okc[i][j]);
			okc[i][j]=(!okc[i][j]);
		}
	if (cul[s]==cul[t] && okc[s][s]) {
		cout<<-1;
		return 0;
	}
	for (int i=1;i<=n;i++)
		for (int j=1;j<=n;j++)
			mp[i][j]=0x3f3f3f3f; 
	for (int i=1;i<=m;i++) {
		int a,b,s;
		scanf("%d%d%d",&a,&b,&s);
		mp[a][b]=s;
		mp[b][a]=s;
	}
	q[1]=s;
	dij(s,1);
	if (tmp[t]==0) {
		cout<<-1;
		return 0;
	}
//	for (int i=1;i<=n;i++)
//		cout<<tmp[i]<<" ";
//	cout<<endl;
	dfs(s,0);
	if (ans==0x3f3f3f3f) cout<<-1;
	else cout<<ans;
	return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...