题目来源:力扣(LeetCode)
题目链接:https://leetcode-cn.com/problems/remove-max-number-of-edges-to-keep-graph-fully-traversable
描述
Alice 和 Bob 共有一个无向图,其中包含 n 个节点和 3 种类型的边:
类型 1:只能由 Alice 遍历。
类型 2:只能由 Bob 遍历。
类型 3:Alice 和 Bob 都可以遍历。
给你一个数组 edges ,其中 edges[i] = [typei, ui, vi] 表示节点 ui 和 vi 之间存在类型为 typei 的双向边。请你在保证图仍能够被 Alice和 Bob 完全遍历的前提下,找出可以删除的最大边数。如果从任何节点开始,Alice 和 Bob 都可以到达所有其他节点,则认为图是可以完全遍历的。
返回可以删除的最大边数,如果 Alice 和 Bob 无法完全遍历图,则返回 -1 。
思路:
对分别Alice和Bob建立最小生成树。先加入3类边中对他们都有贡献的边,随后加入1,3类中对Alice有贡献和2,3类中对Bob有贡献的边,并记入加入的边数,最后用于判断是否都能建立连通图。
class Solution {
public:
int find_top(int *a,int x)
{
int top=x,j=x,t;
while(a[top]!=top)top=a[top];
while(j!=top)
{
t=a[j];
a[j]=top;
j=top;
}
return top;
}
int maxNumEdgesToRemove(int n, vector<vector<int>>& E) {
int *a1,*a2;
int u1,u2,v1,v2,ans=0,m;
int f1=0,f2=0;
bool *f;
a1=new int[n+1];a2=new int[n+1];
for(int i=1;i<=n;i++)a1[i]=a2[i]=i;
m=E.size();
f=new bool[m]();
for(int i=0;i<m;i++)
{
if(E[i][0]==3)
{
u1=find_top(a1,E[i][1]),v1=find_top(a1,E[i][2]);
u2=find_top(a2,E[i][1]),v2=find_top(a2,E[i][2]);
if(u1!=v1&&u2!=v2)
{
a1[u1]=v1;
a2[u2]=v2;
f[i]=true;
f1++,f2++;
}
}
}
for(int i=0;i<m;i++)
{
if(E[i][0]==1)
{
u1=find_top(a1,E[i][1]),v1=find_top(a1,E[i][2]);
if(u1!=v1)a1[u1]=v1,f1++;
else ans++;
}
else if(E[i][0]==2)
{
u2=find_top(a2,E[i][1]),v2=find_top(a2,E[i][2]);
if(u2!=v2)a2[u2]=v2,f2++;
else ans++;
}
else
{
if(f[i])continue;
u1=find_top(a1,E[i][1]),v1=find_top(a1,E[i][2]);
u2=find_top(a2,E[i][1]),v2=find_top(a2,E[i][2]);
if(u1!=v1)a1[u1]=v1,f1++;
else if(u2!=v2)a2[u2]=v2,f2++;
else ans++;
}
}
//cout<<ans<<endl;
if(f1!=n-1||f2!=n-1)ans=-1;
//cout<<f1<<" "<<f2<<endl;
return ans;
}
};
若有什么错误,欢迎指正^ _ ^ 。