FZU2169:shadow(最短路)

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的一条道路。每支军队只能沿着道路走,并且是其所在城市与王都之间的最短路线走。

 Output

输出一行一个整数表示消灭的叛军数量。

 Sample Input

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

 Sample Output

3

简单的最短路SPFA,只是要加个优化,计算好友叛军的城市个数,每消灭一波叛军就减1,当没有叛军了就不用继续SPFA了

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
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<int> 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;
}
时间: 2024-07-28 17:48:30

FZU2169:shadow(最短路)的相关文章

FZU2169 shadow题解

http://acm.fzu.edu.cn/problem.php?pid=2169 Problem Description YL 是shadow国的国王,shadow国有N个城市.为了节省开支,shadow国只有N-1条道路,这N-1条道路使得N个城市连通.某一 年,shadow国发生了叛乱,叛军占领了多个城市,王都岌岌可危.王都为编号为1的城市,除了王都外有K个城市有YL的军队.现在这K支军队要向王都进 军,并且消灭沿途经过的城市中的叛军.现给出N个城市的道路情况以及城市的叛军数量,问总共需

2014 Super Training #10 C Shadow --SPFA/随便搞

原题: FZU 2169 http://acm.fzu.edu.cn/problem.php?pid=2169 这题貌似有两种解法,DFS和SPFA,但是DFS怎么都RE,SPFA也要用邻接表表示边,用向量表示的话会TLE,而且用SPFA有一个异或,就是题目说要沿最短路走到都城,但是SPFA是走最短路去消灭叛军,然后再走回都城,我不知道怎么回事,不知道能不能有大神解释.因为这样的话,有多少叛军就能消灭多少叛军了,那就不要用什么算法 了,直接一个统计.于是试了一下,居然A了,瞬间变成大水题,我无法

passwd、shadow、group结构及各字段含义

/etc/password结构 sample:root:x:0:0:root:/root:/bin/bash 账号名称 密码 UID GID 用户信息说明 家目录 Shell root x 0 0 root /root /bin/bash /etc/shadow结构: sample:root:$1$/30QpE5e$y9N/D0bh6rAACBEz.hqo00:14126:0:99999:7::: 账号名称 密码 最近更动密码的日期 密码不可被更动的天(0代表随时可以变动) 密码需要重新变更的天

hdu3461Marriage Match IV 最短路+最大流

//给一个图.给定起点和终点,仅仅能走图上的最短路 //问最多有多少种走的方法.每条路仅仅能走一次 //仅仅要将在最短路上的全部边的权值改为1.求一个最大流即可 #include<cstdio> #include<cstring> #include<iostream> #include<queue> #include<vector> using namespace std ; const int inf = 0x3f3f3f3f ; const

UESTC30-最短路-Floyd最短路、spfa+链式前向星建图

最短路 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的T-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗? Input 输入包括多组数据. 每组数据第一行是两个整数NN ,MM (N≤100N≤100 ,M≤10000M≤1000

ACM: HDU 2544 最短路-Dijkstra算法

HDU 2544最短路 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗? Input 输入包括多组数据.每组数据第一行是两个整数N.M(N<=100,M<

ACM/ICPC 之 昂贵的聘礼-最短路解法(POJ1062)

//转移为最短路问题,枚举必经每一个不小于酋长等级的人的最短路 //Time:16Ms Memory:208K #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define INF 0x3f3f3f3f #define MAX 105 int lim, n; int p[M

图论(A*算法,K短路) :POJ 2449 Remmarguts&#39; Date

Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 25216   Accepted: 6882 Description "Good man never makes girls wait or breaks an appointment!" said the mandarin duck father. Softly touching his little ducks' head, h

hdu4725 拆点+最短路

题意:有 n 个点,每个点有它所在的层数,最多有 n 层,相邻两层之间的点可以互相到达,消耗 c (但同一层并不能直接到达),然后还有一些额外的路径,可以在两点间互相到达,并且消耗一定费用.问 1 点到 n 点的最小花费 将每一层拆成两个点,分别为进入层和出发层,然后相邻层的出发层可以指向进入层,花费 c,每个点可以到达其出发层,而进入层可以到达该点,花费 0 ,最后建立其余双向边,最短路 1 #include<stdio.h> 2 #include<string.h> 3 #in