网络分析
此题之前已经用邻接矩阵的方法解过,但邻接矩阵要用n*n的二维数组存放,占用空间较大,且间接连接的结点查找过于繁杂,容易溢出,显得有些暴力了。
这次用并查集算法来解决。并查集,顾名思义就是集合的合并与元素(结点)查找的一种算法。其核心思想在于,对于直接或间接连接的结点,把它们归为同一集合,同一集合的结点拥有相同的根结点,以便于操作。
import java.util.Scanner;
class UnionFind//并查集
{static int[] a;//存放每个结点的根节点
UnionFind(int num)//构造方法,初始化状态
{a=new int[num];
for(int i=1;i<a.length;i++)
a[i]=-1;//每个结点的根结点初始是自身
}
void Union(int r1,int r2)//合并操作
{if(Find(r1)==Find(r2))//同根,不用合并
return;
a[r2]=r1;//不同根,规定以r1为根
}
int Find(int r)//查找操作,查找r结点的根结点
{if(a[r]<0)//递归出口,找到根结点
return r;
else
return a[r]=Find(a[r]);//压缩路径,让该路径上的结点都指向根结点,方便查找
}
public static void main(String[] args)
{int n,m,x,y,z;
Scanner sc=new Scanner(System.in);
n=sc.nextInt(); m=sc.nextInt();
UnionFind uf=new UnionFind(n+1);
int[] res=new int[n+1];//存放各结点信息
for(int i=0;i<m;i++)
{x=sc.nextInt(); y=sc.nextInt(); z=sc.nextInt();
if(x==1)
uf.Union(y,z);
else
{res[y]+=z;
for(int j=1;j<=n;j++)
if(j!=y&&uf.Find(y)==uf.Find(j))//结点y与结点j连通
res[j]+=z;
}
}
for(int i=1;i<res.length;i++)
System.out.print(res[i]+" ");
}
}
运行结果:
若有错误或不足之处,请各位批评指正!