struct note
{
int y,next,v;//y节点,next下一个,v之间的权值。
}a[E+8]//E为边数
bool f[][];//好用极了,但耗空间。表示i与j是否相连。
void floyd(){
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
if(d[i][k]+d[k][j]<d[i][j]){
d[i][j]=d[i][k]+d[k][j];//只能用邻接矩阵
path[i][j]=k;
}
}
void dijkstra(int r){
for(int i=1;i<=n;i++)dis[i]=a[r][i];//还是用邻接矩阵,但也可以用邻接表
memset(vis,false,sizeof(vis));//vis用于标记
vis[r]=true;dis[r]=0;//起点赋值
for(int i=1;i<n;i++)//只要循环n-1次
{
int minn=0x3f3f3f3f;
int k=0;
for(int j=1;j<=n;j++)
if((!vis[j])&&(minn>dis[j])){
minn=dis[j];
k=j;
}
}
if(k==0)return;
vis[k]=k;
for(int j=1;j<=n;j++)
if((!vis[j])&&(dis[k]+a[c][j]<dis[j]))
dis[j]=dis[k]+a[k][j];
}
当然,邻接表会更好:
void dijkstra()
{
memset(dis,0x3f3f3f,sizeof(dis));//初始化
vis[1]=1;
dis[1]=0;
for(int i=1;i<=n;++i)
{
int k=0;
for(int j=1;j<=n;++j)//找出距离最近的点
if(!vis[j]&&(k==0||dis[j]<dis[k]))
k=j;
v[k]=1;//加入集合
for(int j=1;j<=n;++j)//松弛
if(!v[j]&&dis[k]+a[k][j]<dis[j])
dis[j]=dis[k]+a[k][j];
}
}
bool Bellman_Ford()//只能判断
{
for(int i=1;i<n;++i)
for(int j=1;j<=e;++j)
relax(edge[j].u,edge[j].v,edge[j].weight);
bool flag=1;
for(int i=1;i<=e;++i)
if(dist[edge[i].v]>dist[edge[i].u]+edge[i].weight)//邻接表!!!
{
flag = 0;
break;
}
return flag;
}
void spfa(int s){
memset(dis,INF,sizeof(dis)); //初始化每点i到s的距离
dis[s]=0;vis[s]=true;q[1]=s; // 队列初始化,s为起点
int v,head=0,tail=1;//队头队尾
while(head<tail){ // 队列非空
head++;
v=q[head]; // 取队首元素
vis[v]=0; // 释放队首结点,因为这节点可能下次用来松弛其它节点,重新入队
for(int i=0; i<=n; i++) // 对所有顶点
if ((a[v][i]>0)and(dis[i]>dis[v]+a[v][i])){
dis[i]=dis[v]+a[v][i]; // 修改最短路
if (!vis[i]){ // 如果扩展结点i不在队列中,入队
q[++tail]=i;
vis[i]=true;
}
}
}
}
void Prim()
{
while(1){//
counter++; //记录边的顺序编号
int minn=56666,pos,start,flag=1;
for(int j = 1;j<=n;j++) { //查找所有连接点集中和非点集中的边的最小边
if(markVertex[j]!=0) {
for (int i=1;i<=n;i++) {
if (markVertex[i]!=0)continue;
if (list[j][i]!=-1 and list[j][i]<minn) {
flag=0;
minn=list[j][i];
pos=i;
start=j;
}
}
}
}
if(flag)break; //如果所有点都在最小生成树中,跳出循环
markEdge[start][pos]=counter; //否则将边导入最小生成树
markVertex[pos]=1; //还有导入对应的集合外的点
}
}//(秀了一波英语,no建议哈)
并查集三工具准备
int Kruskal(int n,int m)
{
int nEdge = 0, res = 0;
qsort(a, n, sizeof(a[0]), cmp);
for(int i = 0; i < n and nEdge != m - 1; i++){
//判断当前这条边的两个端点是否属于同一棵树
if(find(a[i].a) != find(a[i].b)){
unite(a[i].a, a[i].b);
res += a[i].price;
nEdge++;
}
}
//如果加入边的数量小于m - 1,则表明该无向图不连通,等价于不存在最小生成树
if(nEdge < m-1) res = -1;
return res;
}
int G(int x)
{
if(father[x]==x)return x;
father[x]=G(father[x]);
return father[x]
}
void M(int x,int y)
{
int fx,fy;
fx=G(x);
fy=G(y);
father[fx]=fy;
}
bool J(int x,int y)
{
int fx,fy;
fx=G(x);
fy=G(y);
return (fx==fy);
}
———————————————————————————————————————————————