hdu1863

来源:互联网 发布:喀秋莎软件官网下载 编辑:程序博客网 时间:2024/06/05 17:39

和前一年那道畅通工程几乎一模一样,只要在加边过程中增加在整个容器被遍历结束时没有加入顶点数-1条边的判断逻辑,此时无法判断图是否连通,意味着所有边探查结束 所得不是一个连通分支:

克鲁斯卡尔+并查集:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int part[100];
struct node//克鲁斯卡尔算法是加边法,使用node结构表示边信息,而不是prim的数组
{
 int from;
 int to;
 int cost;
};
vector<node> Vec;

int getFa(int n)
{
 if(part[n]==n)return n;
 part[n]=getFa(part[n]);
 return part[n];
}

bool merge(int x,int y)
{
 if(getFa(x)==getFa(y))return false;
 part[getFa(y)]=x;return true;
}
bool cmp(node x,node y)
{
 return x.cost<y.cost;
}
int main()
{
 int n,m;//n为边数目,m为顶点数目
 while(cin>>n>>m&&n)
 {
  Vec.clear();
  for (int i=1;i<=m;i++)part[i]=i;
  int from,to,cost;
  node temp;
  while(n--)
  {
   cin>>from>>to>>cost;
   temp.from=from;
   temp.to=to;
   temp.cost=cost;
   Vec.push_back(temp);   
  }
  sort(Vec.begin(),Vec.end(),cmp);//一开始傻到用vec作为迭代器,汗
  int count=m-1;
  int sum=0;
  for(vector<node>::iterator iter=Vec.begin();iter!=Vec.end();iter++)
   if(merge(iter->from,iter->to))
   {
    sum+=iter->cost;
    count--;
    if(!count)break;
   }
   if(count)cout<<"?"<<endl;
   else cout<<sum<<endl;     
 }
 return 1;
}

 

 

 

普利姆算法: ps  搞不懂为什么用memset初始化是MAX值变为了-1;

#include <iostream>
using namespace std;
#define MAX INT_MAX/2
int map[100][100];
int dist[10000];

void Prim(int m)
{
    int sum=0;
    int tag=1;//标示是否可连通
 
    dist[1]=0;
    for (int i=2;i<=m;i++)dist[i]=map[1][i];
    for (int j=1;j<=m-1;j++)//依次加入剩余n-1个顶点
    {
        int pos,temp=INT_MAX;
        for (int k=2;k<=m;k++)
        {
            if (dist[k]<temp&&dist[k]>0)//如果使用<pos会出现未被赋值情况,加上等于没有什么影响 要不给temp赋更大的初值
            {
                temp=dist[k];
                pos=k;
            }           
        }
        dist[pos]=0;
        if (temp==MAX)
        {
            tag=0;break;
        }
        else sum+=temp;

        for(int t=2;t<=m;t++)
        {
            if (dist[t]>map[pos][t])dist[t]=map[pos][t];
        }
    }
    if(tag==0)cout<<"?"<<endl;
    else cout<<sum<<endl;   
}
int main()
{
    int n,m;
    while (cin>>n>>m&&n)
    {
        int from,to,length;
        //memset(map,MAX,40000);//memset是处理一段连续的内存,以字节为单位,第三个参数是字节数
        for (int k=1;k<=m;k++)
            for(int t=1;t<=m;t++)
                map[k][t]=MAX;
             for(int j=1;j<=m;j++)map[j][j]=0;

        for(int i=1;i<=n;i++)
        {
            cin>>from>>to>>length;
            map[from][to]=length;
            map[to][from]=length;
        }
        Prim(m);
    }
    return 0;
}

原创粉丝点击