第一次搜索完之后形成的图应该是一张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;
}