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

FZU2169:shadow(最短路)

編輯:C++入門知識

Problem Description

YL是shadow國的國王,shadow國有N個城市。為了節省開支,shadow國只有N-1條道路,這N-1條道路使得N個城市連通。某一年,shadow國發生了叛亂,叛軍占領了多個城市,王都岌岌可危。王都為編號為1的城市,除了王都外有K個城市有YL的軍隊。現在這K支軍隊要向王都進軍,並且消滅沿途經過的城市中的叛軍。現給出N個城市的道路情況以及城市的叛軍數量,問總共需要消滅多少叛軍?

\ Input

第一行輸入兩個整數N,K,接下來輸入N(1<=N<=100000)個整數Ai(0<=Ai<=10000),表示第i個城市的叛軍數量。接下來輸入K個大於等於1且小於等於N的整數,表示有軍隊的城市的編號。數據保證王都以及有軍隊的城市沒有叛軍。接下來輸入N-1行,每行兩個整數u、v,表示連接u和v的一條道路。每支軍隊只能沿著道路走,並且是其所在城市與王都之間的最短路線走。<喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KCjxoMj48aW1nIHNyYz0="https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017012114360108.gif" alt="\"> Output

輸出一行一個整數表示消滅的叛軍數量。

\ Sample Input

4 2 0 3 0 0 3 4 1 2 2 3 2 4

\ Sample Output

3 簡單的最短路SPFA,只是要加個優化,計算好友叛軍的城市個數,每消滅一波叛軍就減1,當沒有叛軍了就不用繼續SPFA了
#include 
#include 
#include 
#include 
using namespace std;

const int inf = 1<<30;
const int L = 100005;

struct Edges
{
    int x,y,w,next;
} e[L<<2];

int head[L];
int dis[L];
int vis[L];
int cnt[L],hash[L],ss[L];
int s[L];

void AddEdge(int x,int y,int w,int k)
{
    e[k].x = x,e[k].y = y,e[k].w = w,e[k].next = head[x],head[x] = k;
}
int relax(int u,int v,int c)
{
    if(dis[v]>dis[u]+c)
    {
        dis[v] = dis[u]+c;
        return 1;
    }
    return 0;
}

int SPFA(int src)
{
    int i;
    memset(vis,0,sizeof(vis));
    dis[src] = 0;
    queue Q;
    Q.push(src);
    vis[src] = 1;
    while(!Q.empty())
    {
        int u,v;
        u = Q.front();
        Q.pop();
        vis[u] = 0;
        for(i = head[u]; i!=-1; i=e[i].next)
        {
            v = e[i].y;
            if(relax(u,v,e[i].w)==1 && !vis[v])
            {
                Q.push(v);
                vis[v] = 1;
            }
        }
    }
}

int main()
{
    int t,n,k;
    int i,j;
    while(~scanf("%d%d",&n,&k))
    {
        memset(e,-1,sizeof(e));
        for(i = 1; i<=n; i++)
        {
            dis[i] = inf;
            head[i] = -1;
            hash[i] = 0;
        }
        int cnt = 0;
        for(i = 1; i<=n; i++)
        {
            scanf("%d",&s[i]);
            if(s[i])
            {
                hash[i] = 1;
                cnt++;
            }
        }
        for(i = 1; i<=k; i++)
        {
            scanf("%d",&ss[i]);
        }
        for(i = 0; i<2*(n-1); i+=2)
        {
            int x,y,w;
            scanf("%d%d",&x,&y);
            AddEdge(x,y,1,i);
            AddEdge(y,x,1,i+1);
        }
        int ans = 0;
        for(i = 1; i<=k; i++)
        {
            SPFA(ss[i]);
            for(j = 1; j<=n; j++)
            {
                if(!hash[j])
                    continue;
                if(dis[s[j]]!=inf)
                {
                    hash[j] = 0;
                    cnt--;
                    ans+=s[j];
                }
            }
            if(!cnt)
                break;
        }
        printf("%d\n",ans);
    }

    return 0;
}

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