POJ 3013 Big Christmas Tree(SPFA)(TEST 10-23 )

POJ 3013 Big Christmas Tree

TEST<22> 10-23

解题思路

就是 求最短路
然后 求 各个分支到根节点*边价值求和

AC 代码如下

/* spfa 
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
int head[1000000];
struct map{//记录数组
    int to;
    int next;
    int val;
}p[1000000];
int val[500000],vis[500000];//价值数组,标记数组
long long dis[500000];//累计权重数组
int n,m,ant;
int add(int x,int y,int w){ //添加数据函数
    p[ant].to=y;
    p[ant].val=w;           
    p[ant].next=head[x];   
    printf("ant:%d , to= %d, val = %d ",ant,p[ant].to,p[ant].val);
    cout<<"head["<<x<<"]:"<<head[x]<<endl;
    head[x]=ant++;//ant 作为点的唯一性 标志
return 0;
}
int  spfa(int number){//最短路  spfa算法
    memset(vis,0,sizeof(vis));//标记数组重置,也可以放到t 每组中 组头
    for(int i=0;i<=n;i++)//重置为最大值  
    dis[i]=9999999999;
    dis[number]=0; //初始点没有 儿子,0
    vis[number]=1;//标记访问过
    queue<int> s; 
    s.push(number);
    while(!s.empty()){
        int u=s.front();
        s.pop();
        vis[u]=0;
        for(int i=head[u];i!=-1;i=p[i].next){ //扫描路径 , 进行松弛操作
            int v=p[i].to;
            int w=p[i].val;
            if(dis[v]>dis[u]+w){
                dis[v]=dis[u]+w;
                if(!vis[v]){
                vis[v]=1;
                s.push(v);    
                }
            }
        }
    }
    int flag=0;
    long long sum=0;
    for(int i=1; i<=n;i++){
        if(dis[i]==9999999999){
            flag=1;
            break;
        }
        else
        sum+=dis[i]*val[i];
    }
    if(flag)
    printf("No Answer\n");
    else
    printf("%lld\n",sum);
    return 0;
}
int main(){
    int t;
    scanf("%d",&t);

    while(t--){
        ant=0;
        //每组必须重置 这是  路径指向 函数数组
        memset(head,-1,sizeof(head));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        scanf("%d",&val[i]);
        for(int i=1;i<=m;i++){
            int x,y,w;
            scanf("%d%d%d",&x,&y,&w);
            add(x,y,w);//双向加入,可能存在 x-y-z最大
            add(y,x,w);//双向加入 y-x-z
        }
        for(int i=0;i<=ant;i++)
            printf("ant=%d :to=%d, next=%d, val=%d\n", i,p[i].to,p[i].next,p[i].val);
         for(int i=0;i<=ant;i++)
         cout<<i<<": "<<head[i]<<endl;
        spfa(1);//从1开始 是否存在  可替换(缩小)操作
    }
    return 0;
}

发布了55 篇原创文章 · 获赞 1 · 访问量 980

猜你喜欢

转载自blog.csdn.net/weixin_43556527/article/details/103017110
今日推荐