ACM入门之【图论习题】

P5318 【深基18.例3】查找文献【★ 图的遍历】

在这里插入图片描述
考察的就是基础的图的遍历。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
vector<int>ve[N];
int n,m,st[N];
void dfs(int u)
{
    
    
    cout<<u<<" ";
    st[u]=1;
    for(int i=0;i<ve[u].size();i++) 
        if(!st[ve[u][i]]) dfs(ve[u][i]);
}
void bfs(int u)
{
    
    
    memset(st,0,sizeof st);
    queue<int>q; q.push(u); st[u]=1;
    while(q.size())
    {
    
    
        u=q.front(); q.pop();
        cout<<u<<" ";
        for(int i=0;i<ve[u].size();i++) 
            if(!st[ve[u][i]]) q.push(ve[u][i]),st[ve[u][i]]=1;
    }
}
int main(void)
{
    
    
    cin>>n>>m;
    for(int i=0;i<m;i++)
    {
    
    
        int a,b; scanf("%d%d",&a,&b);
        ve[a].push_back(b);
    }
    for(int i=1;i<=n;i++) sort(ve[i].begin(),ve[i].end());//排序
    dfs(1);
    puts("");
    bfs(1);
    return 0;
}

P3916 图的遍历【★★ 求每一个点可以到达的最大的点 反向建图】

在这里插入图片描述
求一个点到最大的点,等价于最大的点到它可以到达的点。
故我们可以反向建图。从大到小枚举所有的点,如果该点遍历过了,说明有一个更大的点之前来过(因为我们是先枚举大结点),故遍历过的可以不用遍历。那么总的时间复杂度就是线性的O(m),完全可以过。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int h[N],e[N],ne[N],idx;
int st[N],ans[N],n,m; 
void add(int a,int b)
{
    
    
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u,int maxv)
{
    
    
    ans[u]=maxv;
    st[u]=1;
    for(int i=h[u];i!=-1;i=ne[i])
    {
    
    
        int j=e[i];
        if(!st[j]) dfs(j,max(maxv,j));//没有遍历过
    }
}
int main(void)
{
    
    
	memset(h,-1,sizeof h);
	cin>>n>>m;
	for(int i=0;i<m;i++)
	{
    
    
	    int a,b; scanf("%d%d",&a,&b);
	    add(b,a);//反向建图
	}
	for(int i=n;i>=1;i--) if(!st[i]) dfs(i,i);//从大到小枚举
	for(int i=1;i<=n;i++) cout<<ans[i]<<" ";
	return 0;
}

P1113 杂务【★ ★ 拓扑排序 求完成所有杂务所需的最短时间】

在这里插入图片描述
比较容易的想到的是拓扑排序。这好像是拓扑排序的一个非常经典的模型。
但问题是如何求,不难想到的是答案就是最晚的点的结束时间。

例:A完成需要先完成B,C。 故A结束的时间=A需要花费的时间+max(B,C)花费的时间

#include<bits/stdc++.h>
using namespace std;
const int N=1e5*6+10;
typedef long long int LL;
int h[N],e[N],ne[N],idx;
LL w[N],st[N],cnt[N],f[N],n,ans;
void add(int a,int b)
{
    
    
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void topsort()
{
    
    
	queue<int>q;
	for(int i=1;i<=n;i++) if(!cnt[i]) q.push(i),st[i]=1;
	while(q.size())
	{
    
    
		int u=q.front(); q.pop();
		for(int i=h[u];i!=-1;i=ne[i])
		{
    
    
			int j=e[i];
			f[j]=max(f[j],w[u]);//求需要完成的先前任务的最大时间
			if(--cnt[j]==0) 
			{
    
    
				if(!st[j]) q.push(j),st[j]=1,w[j]+=f[j];
			};
		}
	}
	for(int i=1;i<=n;i++) ans=max(ans,w[i]);//枚举所有的点,存最晚结束的时间
	cout<<ans;
}
int main(void)
{
    
    
    memset(h,-1,sizeof h);
	cin>>n;
	for(int i=1;i<=n;i++)
	{
    
    
	    int x,id;
		cin>>id>>x;
		w[id]=x;
		while(cin>>x,x) add(x,id),cnt[id]++;
	}
	topsort();
	return 0;
}

P4017 最大食物链计数【★ ★ 拓扑排序 求链数】

在这里插入图片描述
既然 食物链中的生物 可以看成 节点,那么 最佳生产者 的入度一定为 0, 而 最佳消费者 的出度也为 0。
在这里插入图片描述
例子:B->A, C->A, 故以A为终点的条数等于 到B点的条数+到C点的条数。这是一个递推累加的过程。

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5*5+10;
const int mod=80112002;
int h[N],e[N],ne[N],idx;
int st[N],in[N],out[N],n,m;
LL sum[N],ans;
void add(int a,int b)
{
    
    
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void topsort()
{
    
    
    queue<int>q;
    for(int i=1;i<=n;i++) if(in[i]==0) q.push(i),st[i]=1,sum[i]=1;
    while(q.size())
    {
    
    
        int u=q.front(); q.pop();
        for(int i=h[u];i!=-1;i=ne[i])
        {
    
    
            int j=e[i];
            sum[j]=(sum[j]+sum[u])%mod;
            if(--in[j]==0)
            {
    
    
                if(!st[j]) q.push(j),st[j]=1;
            }
        }
    }
}
int main(void)
{
    
    
    memset(h,-1,sizeof h);
    cin>>n>>m;
    for(int i=0;i<m;i++)
    {
    
    
        int a,b; scanf("%d%d",&a,&b);
        add(a,b);
        out[a]++,in[b]++;
    }
    topsort();
    for(int i=1;i<=n;i++) if(out[i]==0) ans=(ans+sum[i])%mod;//是一条链的结尾
    cout<<ans;
    return 0;
}

P1807 最长路【★ ★ 最长路】

在这里插入图片描述
传统的是最短路,那么如何求最长路呢?只需将边权乘以(-1) 就变成了求最短路。
最后结果记得再乘以(-1)回来就是结果。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
int h[N],e[N],w[N],ne[N],idx;
int st[N],dist[N],n,m;
void add(int a,int b,int c)
{
    
    
    e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
void spfa()
{
    
    
    memset(dist,0x3f,sizeof dist);
    dist[1]=0;
    queue<int>q; q.push(1);
    st[1]=1;
    while(q.size())
    {
    
    
        int u=q.front(); q.pop();
        st[u]=0;
        for(int i=h[u];i!=-1;i=ne[i])
        {
    
    
            int j=e[i];
            if(dist[j]>dist[u]+w[i])
            {
    
    
                dist[j]=dist[u]+w[i];
                if(!st[j]) q.push(j),st[j]=1;
            }
        }
    }
}
int main(void)
{
    
    
    memset(h,-1,sizeof h);
    cin>>n>>m;
    for(int i=0;i<m;i++)
    {
    
    
        int a,b,c; scanf("%d%d%d",&a,&b,&c);
        add(a,b,-c);
    }
    spfa();
    if(dist[n]==0x3f3f3f3f) puts("-1");
    else cout<<-dist[n];
    return 0;
}

P2853 [USACO06DEC]Cow Picnic S【★ 图的遍历】

在这里插入图片描述
对于每一个奶牛所在的农场遍历一遍图。
吐过最后某个农场的计数是k则累加即可。

#include<bits/stdc++.h> 
using namespace std;
const int N=1e5+10;
vector<int>ve[N];
int st[N],cnt[N],a[N],k,n,m;
void dfs(int u)
{
    
    
	cnt[u]++,st[u]=1;
	for(int i=0;i<ve[u].size();i++) 
		if(!st[ve[u][i]]) dfs(ve[u][i]);
}
int main(void)
{
    
    
	cin>>k>>n>>m;
	for(int i=1;i<=k;i++) cin>>a[i];
	for(int i=0;i<m;i++)
	{
    
    
		int a,b; cin>>a>>b;
		ve[a].push_back(b); 
	}
	for(int i=1;i<=k;i++)
	{
    
    
		memset(st,0,sizeof st);
		dfs(a[i]);
	}
	int ans=0;
	for(int i=1;i<=n;i++) if(cnt[i]==k) ans++;
	cout<<ans;
	return 0;
}

P3371 【模板】单源最短路径(弱化版)【★ 最短路】

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
const int N=1e4+10;
const int M=1e5*5+10;
int h[N],e[M],ne[M],w[M],idx;
int st[N],dist[N],n,m,s;
void add(int a,int b,int c)
{
    
    
	e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
void Dijkstra(int s)
{
    
    
	for(int i=1;i<=n;i++) dist[i]=(1ll<<31)-1;
	dist[s]=0;
	priority_queue<pii,vector<pii>,greater<pii> >q; q.push({
    
    0,s});
	while(q.size())
	{
    
    
		auto temp=q.top(); q.pop();
		int u=temp.second;
		if(st[u]) continue;
		st[u]=1;
		for(int i=h[u];i!=-1;i=ne[i])
		{
    
    
			int j=e[i];
			if(dist[j]>dist[u]+w[i])
			{
    
    
				dist[j]=dist[u]+w[i];
				q.push({
    
    dist[j],j});
			}
		}
	}
}
int main(void)
{
    
    
	memset(h,-1,sizeof h);
	scanf("%d%d%d",&n,&m,&s);
	for(int i=1;i<=m;i++)
	{
    
    
		int a,b,c; scanf("%d%d%d",&a,&b,&c);
		add(a,b,c);
	}
	Dijkstra(s);
	for(int i=1;i<=n;i++) cout<<dist[i]<<" ";
}

P1629 邮递员送信【★★ 一去一回的最短路 反向建图】

在这里插入图片描述
问题在于如何求每一个点回去的时候的最短路。
考虑到回去的最短路,故反向建图这样就可以正着跑了。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5*3+10;
typedef pair<int,int> PII;
int h[N],e[N],w[N],ne[N],idx;
int dist[N],st[N],n,m;
void add(int a,int b,int c)
{
    
    
	e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
void Dijkstra(int x)
{
    
    
	memset(dist,0x3f,sizeof dist);
	memset(st,0,sizeof st);
	dist[x]=0;
	priority_queue<PII,vector<PII>,greater<PII> >q; q.push({
    
    0,x});
	while(q.size())	
	{
    
    
		auto temp=q.top(); q.pop();
		int u=temp.second;
		if(st[u]) continue;
		st[u]=1;
		for(int i=h[u];i!=-1;i=ne[i])
		{
    
    
			int j=e[i];
			if(dist[j]>dist[u]+w[i])
			{
    
    
				dist[j]=dist[u]+w[i];
				q.push({
    
    dist[j],j});
			}
		}
	}
}
int main(void) 
{
    
    
	memset(h,-1,sizeof h);
	cin>>n>>m;
	for(int i=0;i<m;i++)
	{
    
    
		int a,b,c; scanf("%d%d%d",&a,&b,&c);
		add(a,b,c);
		add(b+n,a+n,c);//反向建图
	}
	Dijkstra(1);
	int sum=0;
	for(int i=2;i<=n;i++) sum+=dist[i];
	Dijkstra(1+n);
	for(int i=2;i<=n;i++) sum+=dist[i+n];
	cout<<sum<<endl;
	return 0;
}

P4779 【模板】单源最短路径(标准版)【★ 最短路】

在这里插入图片描述

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#include<map>
using namespace std;
const int N=1e5+10;
const int M=1e5*2+10;
typedef pair<int,int> PII;
int h[N],e[M],ne[M],w[M],idx;
int dist[N];
bool st[N];
int n,m,s;
void add(int a,int b,int c)
{
    
    
    e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
void spfa(int s)
{
    
    
    memset(dist,0x3f,sizeof dist);

    dist[s]=0;
    st[s]=true;
    queue<int> q; q.push(s);

    while(q.size())
    {
    
    
        int t=q.front(); q.pop();

        st[t]=false;

        for(int i=h[t];i!=-1;i=ne[i])
        {
    
    
            int j=e[i];
            if(dist[j]>dist[t]+w[i])
            {
    
    
                dist[j]=dist[t]+w[i];
                if(!st[j]) q.push(j),st[j]=true;
            }
        }
    }
}
int main(void)
{
    
    
    memset(h,-1,sizeof h);
    scanf("%d%d%d",&n,&m,&s);
    while(m--)
    {
    
    
        int a,b,c; scanf("%d%d%d",&a,&b,&c);
        add(a,b,c);
    }
    spfa(s);
    for(int i=1;i<=n;i++) cout<<dist[i]<<" ";
    cout<<endl;
    return 0;
}

P1144 最短路计数【★★ 统计最短路的数量】

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
const int M=1e6*4+10;
const int mod=100003;
int h[N],e[M],ne[M],idx;
int cnt[N],dist[N],n,m;
void add(int a,int b) {
    
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;}
void bfs()
{
    
    
	memset(dist,0x3f,sizeof dist);
	dist[1]=0,cnt[1]=1;
	queue<int>q; q.push(1);
	while(q.size())
	{
    
    
		int u=q.front(); q.pop();
		for(int i=h[u];i!=-1;i=ne[i])
		{
    
    
			int j=e[i];
			if(dist[j]>dist[u]+1)
			{
    
    
				dist[j]=dist[u]+1;
				cnt[j]=cnt[u];
				q.push(j);
			}else if(dist[j]==dist[u]+1) 
			{
    
    
				cnt[j]=(cnt[j]+cnt[u])%mod;
			}
		}
	}
}
int main(void)
{
    
    
	memset(h,-1,sizeof h);
	cin>>n>>m;
	for(int i=0;i<m;i++)
	{
    
    
		int a,b; cin>>a>>b;
		add(a,b),add(b,a);
	}
	bfs();
	for(int i=1;i<=n;i++) cout<<cnt[i]<<endl;
	return 0;
}

P3366 【模板】最小生成树【★ 最小生成树】

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
int p[N],n,m;
struct node{
    
    int a,b,c;};
bool cmp(node a,node b){
    
    return a.c<b.c;}
vector<node>ve; 
int find(int x)
{
    
    
	if(x!=p[x]) p[x]=find(p[x]);
	return p[x];
}
int f()
{
    
    
	int res=0,cnt=0;
	for(int i=1;i<=n;i++) p[i]=i;
	sort(ve.begin(),ve.end(),cmp);
	for(int i=0;i<ve.size();i++)
	{
    
    
		int a=ve[i].a,b=ve[i].b,c=ve[i].c;
		if(find(a)!=find(b))
		{
    
    
			p[find(a)]=find(b);
			res+=c;
			cnt++;
		}
	}
	if(cnt==n-1) return res;
	else return -1;
}
int main(void)
{
    
    
	cin>>n>>m;
	while(m--)
	{
    
    
		int a,b,c; cin>>a>>b>>c;
		ve.push_back({
    
    a,b,c});
	}
	int ans=f();
	if(ans==-1) puts("orz");
	else cout<<ans;
	return 0;
}

P2872 [USACO07DEC]Building Roads S【★★ 最小生成树】

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
typedef pair<double,double> PII;
struct node
{
    
    
    int a,b;
    double c;
};
bool cmp(node a,node b){
    
    return a.c<b.c;}
int n,m,p[N];
vector<node>ve;
vector<PII>a;
int find(int x)
{
    
    
    if(x!=p[x]) p[x]=find(p[x]);
    return p[x];
}
double get(PII a,PII b)
{
    
    
    double x=(a.first-b.first)*(a.first-b.first);
    double y=(a.second-b.second)*(a.second-b.second);
    return sqrt(x+y);
}
void solve()
{
    
    
    double ans=0;
    sort(ve.begin(),ve.end(),cmp);
    for(int i=0;i<ve.size();i++)//最小生成树
    {
    
    
        int a=ve[i].a,b=ve[i].b;
        double c=ve[i].c;
        if(find(a)==find(b)) continue;
        p[find(a)]=find(b);
        ans+=c;
    }
    printf("%.2lf",ans);
}
int main(void)
{
    
    
    cin>>n>>m;
    for(int i=0;i<n;i++)
    {
    
    
        double x,y; cin>>x>>y;
        a.push_back({
    
    x,y});
    }
    for(int i=1;i<=n;i++) p[i]=i;
    for(int i=0;i<m;i++)
    {
    
    
        int a,b; cin>>a>>b;
        p[find(a)]=find(b);
    }
    for(int i=0;i<n;i++)
        for(int j=i+1;j<n;j++)//存所有的边
        {
    
    
            double c=get(a[i],a[j]);
            ve.push_back({
    
    i+1,j+1,c});
        }
    solve();
    return 0;
}

P1991 无线通讯网【★★ 最小生成树】

在这里插入图片描述
也就是说卫星电话是无需距离的。
我们先构造一个最小生成树,然后再减边。让其用卫星电话。
例如: 3给卫星电话 可以减2条边

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=1e5+10;
struct node{
    
    int a,b;double c;};
bool cmp(node a,node b){
    
    return a.c<b.c;}
int m,n,p[N];
vector<node>ve;
vector<PII>a;
int find(int x)
{
    
    
    if(x!=p[x]) p[x]=find(p[x]);
    return p[x];
}
double get(PII a,PII b)
{
    
    
    int x=(a.first-b.first)*(a.first-b.first);
    int y=(a.second-b.second)*(a.second-b.second);
    return sqrt(x+y);
}
void sovle()
{
    
    
    for(int i=1;i<=n;i++) p[i]=i;
    vector<double>s;
    sort(ve.begin(),ve.end(),cmp);
    for(int i=0;i<ve.size();i++)
    {
    
    
        int a=ve[i].a,b=ve[i].b;
        double c=ve[i].c;
        if(find(a)==find(b)) continue;
        s.push_back(c);
        p[find(a)]=find(b);
    }
    sort(s.begin(),s.end());
    printf("%.2lf",s[s.size()-1-(m-1)]);
}
int main(void)
{
    
    
    cin>>m>>n;
    for(int i=0;i<n;i++) 
    {
    
    
        int x,y; cin>>x>>y;
        a.push_back({
    
    x,y});
    }
    for(int i=0;i<n;i++)
        for(int j=i+1;j<n;j++)
        {
    
    
            double c=get(a[i],a[j]);
            ve.push_back({
    
    i+1,j+1,c});
        }
    sovle();
    return 0;
}

P1396 营救【★★ 最小生成树 让一个点到另一个点的最大值最小】

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
struct node{
    
    int a,b,c;};
bool cmp(node a,node b){
    
    return a.c<b.c;}
int p[N],n,m,s,t;
vector<node>ve;
int find(int x)
{
    
    
    if(x!=p[x]) p[x]=find(p[x]);
    return p[x];
}
void solve()
{
    
    
    for(int i=1;i<=n;i++) p[i]=i;
    sort(ve.begin(),ve.end(),cmp);
    for(int i=0;i<m;i++)
    {
    
    
        int a=ve[i].a,b=ve[i].b,c=ve[i].c;
        p[find(a)]=find(b);
        if(find(s)==find(t)) //说明联通了
        {
    
    
            cout<<c;
            return;
        }
    }
}
int main(void)
{
    
    
    cin>>n>>m>>s>>t;
    for(int i=0;i<m;i++)
    {
    
    
        int a,b,c; cin>>a>>b>>c;
        ve.push_back({
    
    a,b,c});
    }
    solve();
    return 0;
}

P2121 拆地毯【★★ 最小生成树的变种】

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int p[N],n,m,k;
struct node{
    
    int a,b,c;};
bool cmp(node a,node b){
    
    return a.c>b.c;}//从大到小排
vector<node>ve;
int find(int x)
{
    
    
    if(x!=p[x]) p[x]=find(p[x]);
    return p[x];
}
void solve()
{
    
    
    for(int i=1;i<=n;i++) p[i]=i;
    sort(ve.begin(),ve.end(),cmp);
    int cnt=0,ans=0;
    for(int i=0;i<ve.size();i++)
    {
    
    
        int a=ve[i].a,b=ve[i].b,c=ve[i].c;
        if(find(a)==find(b)) continue;
        ans+=c,cnt++;
        p[find(a)]=find(b);
        if(cnt>=k) break;
    }
    cout<<ans;
}
int main(void)
{
    
    
    cin>>n>>m>>k;
    for(int i=0;i<m;i++)
    {
    
    
        int a,b,c; cin>>a>>b>>c;
        ve.push_back({
    
    a,b,c});
    }
    solve();
    return 0;
}

P1194 买礼物【★★ 最小生成树】

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int price,n,g[N][N],p[N];
struct node{
    
    int a,b,c;};
vector<node>ve;
bool cmp(node a,node b){
    
    return a.c<b.c;}
int find(int x)
{
    
    
    if(x!=p[x]) p[x]=find(p[x]);
    return p[x];
}
void solve()
{
    
    
    for(int i=1;i<=n;i++) p[i]=i;
    sort(ve.begin(),ve.end(),cmp);
    int cnt=1,w=price;
    for(int i=0;i<ve.size();i++)
    {
    
    
        int a=ve[i].a,b=ve[i].b,c=ve[i].c;
        if(find(a)==find(b)) continue;
        if(c>=price) continue;//也就是说不如直接买
        w+=c,cnt++;
        p[find(a)]=find(b);
    }
    cout<<(n-cnt)*price+w;//(n-cnt) 就是还没买的
}
int main(void)
{
    
    
    cin>>price>>n;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++) cin>>g[i][j];
    for(int i=1;i<=n;i++)
        for(int j=i;j<=n;j++)
            if(g[i][j]) ve.push_back({
    
    i,j,g[i][j]});
    solve();
    return 0;
}

P1195 口袋的天空【★★ 最小生成树】

在这里插入图片描述
先构造最小生成树,再减最大的边让其变成k个连通块

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
struct node{
    
    int a,b,c;};
int p[N],n,m,k,ans;
bool cmp(node a,node b){
    
    return a.c<b.c;}
vector<node>ve;
int find(int x)
{
    
    
    if(x!=p[x]) p[x]=find(p[x]);
    return p[x];
}
void kruskal()
{
    
    
    for(int i=1;i<=n;i++) p[i]=i;
    sort(ve.begin(),ve.end(),cmp);
    vector<int>s;
    int ans=0;
    for(int i=0;i<ve.size();i++)
    {
    
    
        int a=ve[i].a,b=ve[i].b,c=ve[i].c;
        if(find(a)==find(b)) continue;
        p[find(a)]=find(b);
        s.push_back(c);
        ans+=c;
    }
    sort(s.begin(),s.end());
    reverse(s.begin(),s.end());//让其从大到小排序
    map<int,int>mp;
    for(int i=1;i<=n;i++) mp[find(i)]++;//连通块的数量
    if(mp.size()>k||n<k) puts("No Answer");
    else
    {
    
    
        k=k-mp.size();//需要减几条边
        for(int i=0;i<k;i++)  ans-=s[i];
        cout<<ans;
    }
}
int main(void)
{
    
    
    cin>>n>>m>>k;
    for(int i=0;i<m;i++)
    {
    
    
        int a,b,c; cin>>a>>b>>c;
        ve.push_back({
    
    a,b,c});
    }
    kruskal();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_46527915/article/details/123644733