题意:给出一个带权无向图 , 假设存在这样一个子图:子图中至少两个点 , 并且连通 , 子图中的最小边权 ,要比边界边的最大值大(边界边是指 , 一个点在子图中 , 另一个点不在子图中) , 问 ,所有这样子图的顶点数总和是多少?
解法:kruskal的思想,先将边权大的连接,然后判断是否满足 ,
依次连接即可!
我们先考虑用kruskal算法求最大生成树的过程 , 假如我们要加入一条新边 ,如果这条新边上的点和以前已经加入的一些点是可到达的(在这个还未形成的最大生成树上) , 如果这样子图存在 ,那么这个子图肯定包括所有以前加入并且和当前加入点相连(可到达)的点。
代码:
#include
#include
#include
#include
#include
using namespace std;
#define MAXN 5010
#define INF 0x3f3f3f3f
#define min(x , y) (x)<(y)?(x):(y)
struct node
{
int x ,y;
int w;
}edge[MAXN*2505];
struct node1
{
int x;
int w;
}e;
int p[MAXN];
vectorgrap[MAXN];
int n , m , minx , maxx;
int fa;
int num[MAXN];
bool cmp(node x , node y)
{
return x.w<= y.w;
}
void init()
{
for(int i =0; i <= n; i++)
{
p[i] = i;
grap[i].clear();
}
}
int find(int x)
{
int g = x ,h;
while(x !=p[x])
x = p[x];
while(p[g]!= x)
{
h =p[g];
p[g] =x;
g = h;
}
returnx;
}
bool check(int fa)
{
int i ,j;
int minx =INF , maxx = 0;
int x;
for(i = 1; i<= n; i++)
{
x =find(i);
if(x !=fa)
continue;
for(j = 0; j< grap[i].size(); j++)
{
x =find(grap[i][j].x);
if(x ==fa)
{
if(grap[i][j].w < minx)
minx =grap[i][j].w;
}
else
if(grap[i][j].w >maxx)
maxx = grap[i][j].w;
}
}
if(maxx< minx)
return true;
else returnfalse;
}
int kruskal()
{
sort(edge ,edge+m , cmp); //对边进行排序
int i , x ,y , k = 0;
for(i = 1; i<= n; i++)
p[i]= i;
for(i = 1; i<= n; i++)
num[i] = 1;
int sum =0;
for(i = m-1;i >= 0; i--)
{
x =find(edge[i].x); // 判断这两个点是不是在同一颗树上
y =find(edge[i].y);
if(x !=y)
{
if(k ==(n-2))
break;
p[x] =y;
num[y] +=num[x];
if(check(y))
sum += num[y];
k +=1;
}
}
returnsum+n;
}
int main()
{
int t;
cin>>t;
while(t--)
{
int i;
scanf("%d%d" , &n , &m) ;
init();
for(i = 0; i< m; i++)
{
scanf("%d %d%d" , &edge[i].x , &edge[i].y ,&edge[i].w);
e.x =edge[i].y , e.w = edge[i].w;
grap[edge[i].x].push_back(e);
e.x =edge[i].x;
grap[edge[i].y].push_back(e);
}
i =kruskal();
cout<<i<<endl;
}
return0;
}
解法:kruskal的思想,先将边权大的连接,然后判断是否满足
我们先考虑用kruskal算法求最大生成树的过程 , 假如我们要加入一条新边 ,如果这条新边上的点和以前已经加入的一些点是可到达的(在这个还未形成的最大生成树上) , 如果这样子图存在 ,那么这个子图肯定包括所有以前加入并且和当前加入点相连(可到达)的点。
代码:
#include
#include
#include
#include
#include
using namespace std;
#define MAXN 5010
#define INF 0x3f3f3f3f
#define min(x , y)
struct node
{
}edge[MAXN*2505];
struct node1
{
}e;
int p[MAXN];
vectorgrap[MAXN];
int n , m , minx , maxx;
int fa;
int num[MAXN];
bool cmp(node x , node y)
{
}
void init()
{
}
int find(int x)
{
}
bool check(int fa)
{
}
int kruskal()
{
}
int main()
{
}