zoukankan      html  css  js  c++  java
  • hdu 5545 The Battle of Guandu spfa最短路

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5545

    题意:有N个村庄, M 个战场; $ 1 <=N,M <= 10^5 $;

    其中曹操会从第i个村庄中选出若个人 在x[i]战场为其作战, 同时第i个村庄也会有相同的人数在y[i]战场为袁绍作战;

    每个战场i 有对应的重要度w[i],w[i]的值为 0,1,2;

    w[i]为2的战场,要求曹操的兵数(从村庄得到的) 严格大于 袁绍的兵的数量;

    w[i]为1的战场,曹操的兵数不少于袁绍的兵即可;

    w[i]为0的兵,没限制要求;

    并且每个村庄派出一个兵有对应的花费c[i], 问要使得曹操在所有的战场士兵人数满足上面的要求,曹操至少花费为多少/

    思路:

    以贪心的思想很容易想到应该从重要程度为2的村庄开始考虑,如果村庄 i满足w[i]等于2,那么曹操先往该村庄派遣一个士兵;那么由题意知,在y[i]战场 袁绍的并多了1个;怎么办?

    是不是曹操就需要往y[i]战场添加士兵呢?

    不一定,需要看y[i]战场的重要程度,如果重要程度为0呢~~

    所以只需要**递推**到重要程度为0的战场即可;

    那怎么考虑花费最少呢?

    以每个村庄的**价格**作为边的权值,求出所有w[i]为2的点到最近的w[j] = 0的最短路即可;

    但如果直接建边,以重要度为2的战场作为源点spfa到重要度为0的重点,得到的将是曹操为重要度为0的战场的花费;所以反向建边,开始将W[i] = 0的放入队列即可;

    spfa解法:

      1 #pragma comment(linker, "/STACK:1024000000,1024000000")
      2 #include<bits/stdc++.h>
      3 using namespace std;
      4 #define rep0(i,l,r) for(int i = (l);i < (r);i++)
      5 #define rep1(i,l,r) for(int i = (l);i <= (r);i++)
      6 #define rep_0(i,r,l) for(int i = (r);i > (l);i--)
      7 #define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
      8 #define MS0(a) memset(a,0,sizeof(a))
      9 #define MS1(a) memset(a,-1,sizeof(a))
     10 #define MSi(a) memset(a,0x3f,sizeof(a))
     11 #define pb push_back
     12 #define MK make_pair
     13 #define A first
     14 #define B second
     15 #define clear0 (0xFFFFFFFE)
     16 #define inf 0x3f3f3f3f
     17 #define INF 0x3f3f3f3f3f3f3f3f
     18 #define eps 1e-8
     19 #define mod 1000000007
     20 #define zero(x) (((x)>0?(x):-(x))<eps)
     21 #define bitnum(a) __builtin_popcount(a)
     22 #define lowbit(x) (x&(-x))
     23 #define K(x) ((x)*(x))
     24 #define debug(x) printf(" ---- %d
    ",x)
     25 typedef pair<int,int> PII;
     26 typedef long long ll;
     27 typedef unsigned int uint;
     28 typedef unsigned long long ull;
     29 template<typename T>
     30 void read1(T &m)
     31 {
     32     T x = 0,f = 1;char ch = getchar();
     33     while(ch <'0' || ch >'9'){ if(ch == '-') f = -1;ch=getchar(); }
     34     while(ch >= '0' && ch <= '9'){ x = x*10 + ch - '0';ch = getchar(); }
     35     m = x*f;
     36 }
     37 template<typename T>
     38 void read2(T &a,T &b){read1(a);read1(b);}
     39 template<typename T>
     40 void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}
     41 template<typename T>
     42 void out(T a)
     43 {
     44     if(a>9) out(a/10);
     45     putchar(a%10+'0');
     46 }
     47 inline ll gcd(ll a,ll b){ return b == 0? a: gcd(b,a%b); }
     48 inline ll lcm(ll a,ll b){ return a/gcd(a,b)*b; }
     49 template<class T1, class T2> inline void gmax(T1& a, T2 b){ if(a < b) a = b;}
     50 template<class T1, class T2> inline void gmin(T1& a, T2 b){ if(a > b) a = b;}
     51 const int dx[] = {-1,0,1,0}, dy[] = {0,1,0,-1};
     52 const int maxn = 100007;
     53 int head[maxn], tot;
     54 ll dist[maxn], vs[maxn];
     55 void init(){
     56     MS0(head);
     57     MSi(dist);
     58     tot = 0;
     59 }
     60 struct edge{
     61     int to, w, nxt;
     62 } e[maxn << 1];
     63 
     64 void ins(int u,int v,int w)
     65 {
     66     e[++tot].nxt = head[u];
     67     e[tot].to = v;
     68     e[tot].w = w;
     69     head[u] = tot;
     70 }
     71 int x[maxn], y[maxn], c[maxn], w[maxn];
     72 int que[maxn];
     73 ll build(int n, int m)
     74 {
     75     int h = 0, t = 0;
     76     rep1(i,1,n){
     77         ins(y[i], x[i], c[i]);
     78         if(w[y[i]] == 0 && dist[y[i]] == INF)
     79             que[t++] = y[i], dist[y[i]] = 0;
     80     }
     81     while(h < t){
     82         int u = que[h++]; vs[u] = 0;
     83         for(int id = head[u]; id; id = e[id].nxt){
     84             int v = e[id].to, w = e[id].w;
     85             if(dist[v] > dist[u] + w){
     86                 dist[v] = dist[u] + w;
     87                 if(vs[v] == 0){
     88                     que[t++] = v;
     89                     vs[v] = 1;
     90                 }
     91             }
     92         }
     93     }
     94     ll ans = 0;
     95     for(int i = 1; i <= m; i++) if(w[i] == 2){
     96         if(dist[i] == INF) return -1;
     97         ans += dist[i];
     98     }
     99     return ans;
    100 }
    101 int main()
    102 {
    103     //freopen("data.txt","r",stdin);
    104     //freopen("out.txt","w",stdout);
    105     int T, kase = 1;
    106     scanf("%d",&T);
    107     while(T--){
    108         init();
    109         int n, m;
    110         read2(n, m);
    111         rep1(i,1,n) read1(x[i]);
    112         rep1(i,1,n) read1(y[i]);
    113         rep1(i,1,n) read1(c[i]);
    114         rep1(i,1,m) read1(w[i]);
    115         printf("Case #%d: %I64d
    ",kase++, build(n, m));
    116     }
    117     return 0;
    118 }
  • 相关阅读:
    Helvetic Coding Contest 2017 online mirror (teams allowed, unrated) J
    ROS_Kinetic_19 群机器人框架示例(micros swarm framework)
    ROS_Kinetic_18 使用V-Rep3.3.1和Matlab2015b(vrep_ros_bridge)续
    ROS_Kinetic_17 使用V-Rep3.3.1(vrep_ros_bridge)
    USB OTG原理+ ID 检测原理
    高通QSD MSM APQ区别
    qualcomm memory dump 抓取方法
    msm8974 camera driver添加新摄像头kernel hal修改
    现代控制理论-章节组织结构和仿真应用案例详细分析
    ROS_Kinetic_16 ubuntu中安装使用Matlab和ROS
  • 原文地址:https://www.cnblogs.com/hxer/p/5773120.html
Copyright © 2011-2022 走看看