关于这道题使用拓扑排序的可能性
查看原帖
关于这道题使用拓扑排序的可能性
471529
肖翔楼主2023/3/17 18:34

第一次搜索完之后形成的图应该是一张DAG吧(?),而要保证每个点都被访问到,实际上每个点都要找出一条通向它的边,用拓扑序求出的权值最小的这条边,并统计答案可做吗?自己写了份代码,但这个做法似乎假了

附上MLE且会WA的代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=2e6+10;
int n,m;
int h[maxn];


struct ffedge{
	int y,val;
};
vector<ffedge>edggg[maxn];
inline void add(int x,int y,int val){
	edggg[x].push_back((ffedge){y,val});
	return;
}

struct edge{
	int y,val;
};
vector<edge>e[maxn];
bool vis[maxn];
int cnt;
int in[maxn],val[maxn];
inline int bfs(){
	queue<int>q;
	int ans=1;
	q.push(1);
	vis[1]=1;
	while(!q.empty()){
		int u=q.front();
		q.pop();
		for(int i=0;i<edggg[u].size();i++){
			int v=edggg[u][i].y;
			e[u].push_back((edge){v,edggg[u][i].val});
			in[v]++;
			if(vis[v])continue;
			vis[v]=1;
			ans++;
			q.push(v);
		}
	}
	return ans;
}

signed main(){
	freopen("d1.in","r",stdin);
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%lld",&h[i]);
	}
	for(int i=1;i<=m;i++){
		int x,y,val;
		scanf("%lld%lld%lld",&x,&y,&val);
		if(h[x]>=h[y])add(x,y,val);
		if(h[y]>=h[x])add(y,x,val);
	}
	cout<<bfs()<<" ";
	queue<int>q;
	q.push(1);
	memset(vis,0,sizeof(vis));
	memset(val,0x7f,sizeof(val));
	int ans=0;
	while(!q.empty())
	{
		int m=q.front();
		q.pop();
		for(int j=0;j<e[m].size();j++)
		{
			int u=e[m][j].y;
			in[u]--;
			val[u]=min(val[u],e[m][j].val);
			if(!in[u]&&!vis[u])q.push(u),ans+=val[u],vis[u]=1;
		}
	}
	printf("%lld",ans);
	return 0;
}
2023/3/17 18:34
加载中...