讨论正解(with my code)
查看原帖
讨论正解(with my code)
1457160
Hugooo楼主2025/7/21 15:50

我认为这道题不一定是什么搜索什么剪枝吧,虽然题目出错了orz

我觉得可以把这道题看作分层图来跑,以 已经学习了的文化 为状态,配合Dijkstra的贪心策略解答,bitset来存储状态,每次拓展边时判断是否矛盾再q.push()。

当然我的做法也不能保证正确性,可能有错误欢迎指出,如果有hack数据的话那么多多益善orz

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e2+5;
int n,m,k,s,t;
int c[maxn];
bitset<maxn> a[maxn];
int fst[maxn],L = 1;
int dis[maxn];
bool vis[maxn];
struct Node{
	int v;
	int len;
	bitset<maxn> bit;
	bool operator<(const Node &temp)const{
		return len > temp.len;
	}
};
struct Edge{
	int v;
	int w;
	int next;
}edges[20005];
void addedge(int u,int v,int w){
	edges[L].w = w;
	edges[L].v = v;
	edges[L].next = fst[u];
	fst[u] = L++;
}
priority_queue<Node> q;
void Dijkstra(int s){
	bitset<maxn> bits;
	bits[c[s]] = 1;
	dis[s] = 0;
	q.push({s,0,bits});
	while(!q.empty()){
		Node cur = q.top();
		q.pop();
		int u = cur.v;
		if(vis[u]) continue;
		vis[u] = true;
		
		for(int p = fst[u]; p ; p = edges[p].next){
			int w = edges[p].w;
			int v = edges[p].v;
			bitset<maxn> temp = cur.bit; 
			bitset<maxn> next = (a[c[v]] & temp);
			if(next.any() || temp[c[v]]) continue;
			
			temp[c[v]] = 1;
			if(dis[u] + w < dis[v]){
				dis[v] = dis[u] + w;
				q.push({v,dis[v],temp});
			}
		}
	}
}
int main(){
	scanf("%d%d%d%d%d",&n,&k,&m,&s,&t);
	for(int i=1;i<=n;i++) scanf("%d",&c[i]);
	for(int i=1;i<=k;i++){
		for(int j=1;j<=k;j++){
			int temp;
			scanf("%d",&temp);
			a[i][j] = temp;
		}
	}
	int x,y,w;
	for(int i=1;i<=m;i++){
		scanf("%d%d%d",&x,&y,&w);
		addedge(x,y,w);
		addedge(y,x,w);
	}
	for(int i=1;i<=n;i++){
		dis[i] = INT_MAX;
	}
	Dijkstra(s);
	if(dis[t] == INT_MAX){
		printf("-1\n");
	}else{
		printf("%d\n",dis[t]);
	}
	return 0;
}
/*
in:
3 2 3 1 3
1 2 1
0 0
0 0
1 2 1
1 3 1
2 3 1
out:
-1
*/
2025/7/21 15:50
加载中...