程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> poj 3013 big christmas tree

poj 3013 big christmas tree

編輯:C++入門知識

看似不是單源點最短路的,單源點最短路。其實這個題目說讓你求出這些邊的價值,剛開始誤以為是最小生成樹,挺像的,但是邊的權值你不好算。因為每條邊的權值= (sum of weights of all descendant nodes) × (unit price of the edge),然後腦子裡面yy出一張圖,其實你算每個節點的價值,算出然後求和就是這個題目要求的。然後單源點最短路徑就出現了,直接套用spfa模板,然後就水過了。呵呵。

[cpp]
<SPAN style="FONT-SIZE: 18px">#include<iostream> 
#include<queue>  
#include<cstring>  
#include<stdio.h>  
using namespace std; 
struct edge{ 
    long long start; 
    long long end; 
    long long len; 
    long long next; 
}; 
long long tot; 
long long list[50010]; 
edge D[100010]; 
long long dist[50010]; 
bool vis[50010]; 
long long weight[50010]; 
void add(long long a,long long b,long long c) 

    tot=tot+1; 
    D[tot].start=a; 
    D[tot].end=b; 
    D[tot].len=c; 
    D[tot].next=list[a]; 
    list[a]=tot; 

void spfa() 

    long long i; 
    queue<long long> qu; 
    long long now=1; 
    memset(vis,false,sizeof(vis)); 
    memset(dist,-1,sizeof(dist)); 
    vis[now]=true; 
    dist[now]=0; 
    qu.push(now); 
    while(!qu.empty()) 
    { 
        now=qu.front(); 
        qu.pop(); 
        vis[now]=false; 
        for(i=list[now];i!=-1;i=D[i].next) 
        { 
            long long temp; 
            temp=dist[now]+D[i].len; 
            if(temp<dist[D[i].end]||dist[D[i].end]==-1) 
            { 
                dist[D[i].end]=temp; 
                if(vis[D[i].end]==false) 
                { 
                    vis[D[i].end]=true; 
                    qu.push(D[i].end); 
                } 
            } 
        } 
    } 

int main() 

    long long T,sum,i,m,n,a,b,c,flag; 
    cin>>T; 
    while(T--) 
    { 
        memset(list,-1,sizeof(list)); 
        sum=0; 
        flag=0; 
        tot=0; 
        cin>>n>>m; 
        for(i=1;i<=n;i++) 
            scanf("%lld",&weight[i]); 
        for(i=1;i<=m;i++) 
        { 
            scanf("%lld%lld%lld",&a,&b,&c); 
            add(a,b,c); 
            add(b,a,c); 
        } 
        spfa(); 
        for(i=2;i<=n;i++) 
        { 
            if(dist[i]==-1) 
            { 
                flag=1; 
                break; 
            } 
            sum=sum+weight[i]*dist[i]; 
        } 
        if(flag==1) 
            cout<<"No Answer"<<endl; 
        else cout<<sum<<endl; 
    } 
    return 0; 

 
</SPAN> 

#include<iostream>
#include<queue>
#include<cstring>
#include<stdio.h>
using namespace std;
struct edge{
 long long start;
 long long end;
 long long len;
 long long next;
};
long long tot;
long long list[50010];
edge D[100010];
long long dist[50010];
bool vis[50010];
long long weight[50010];
void add(long long a,long long b,long long c)
{
 tot=tot+1;
 D[tot].start=a;
 D[tot].end=b;
 D[tot].len=c;
 D[tot].next=list[a];
 list[a]=tot;
}
void spfa()
{
 long long i;
 queue<long long> qu;
 long long now=1;
 memset(vis,false,sizeof(vis));
 memset(dist,-1,sizeof(dist));
 vis[now]=true;
 dist[now]=0;
 qu.push(now);
 while(!qu.empty())
 {
  now=qu.front();
  qu.pop();
  vis[now]=false;
  for(i=list[now];i!=-1;i=D[i].next)
  {
   long long temp;
   temp=dist[now]+D[i].len;
   if(temp<dist[D[i].end]||dist[D[i].end]==-1)
   {
    dist[D[i].end]=temp;
    if(vis[D[i].end]==false)
    {
     vis[D[i].end]=true;
     qu.push(D[i].end);
    }
   }
  }
 }
}
int main()
{
 long long T,sum,i,m,n,a,b,c,flag;
 cin>>T;
 while(T--)
 {
  memset(list,-1,sizeof(list));
  sum=0;
  flag=0;
  tot=0;
  cin>>n>>m;
  for(i=1;i<=n;i++)
   scanf("%lld",&weight[i]);
  for(i=1;i<=m;i++)
  {
   scanf("%lld%lld%lld",&a,&b,&c);
   add(a,b,c);
   add(b,a,c);
  }
  spfa();
  for(i=2;i<=n;i++)
  {
   if(dist[i]==-1)
   {
    flag=1;
    break;
   }
   sum=sum+weight[i]*dist[i];
  }
  if(flag==1)
   cout<<"No Answer"<<endl;
  else cout<<sum<<endl;
 }
 return 0;
}

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved