• Candies(差分约束)


    http://poj.org/problem?id=3159

    题意:

    flymouse是幼稚园班上的班长,一天老师给小朋友们买了一堆的糖果,由flymouse来分发,在班上,
    flymouse和snoopy是死对头,两人势如水火,不能相容,因此fly希望自己分得的糖果数尽量多于
    snoopy,而对于其他小朋友而言,则只希望自己得到的糖果不少于班上某某其他人就行了。

    比如A小朋友强烈希望自己的糖果数不能少于B小朋友m个,即B- A<=m,A,B分别为
    A、B小朋友的分得的糖果数。这样给出若干组这样的条件,要使fly最后分得的糖果数s1和snoopy
    最后分得的糖果数s2差别取到最大!即s2-s1取最大.

    思路:求源点1到n的最短距离。Dijstra+邻接表

    不过直接用dij会超时。可以用优先队列优化一下。不过运算符重载那里被卡了好久。悲惨的教训啊。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<queue>
     4 using namespace std;
     5 
     6 const int INF = 0x3f3f3f3f;
     7 const int maxv = 30100;
     8 const int maxe = 150100;
     9 struct node
    10 {
    11     int v,w,next;
    12 }edge[maxe];//邻接表
    13 
    14 struct node1
    15 {
    16     int v,c;
    17     bool operator < (const node1 &t) const
    18     {
    19         return c > t.c;//距离从小到大排序
    20     }
    21 };//存每个节点和它到源点的最短距离。
    22 
    23 int n,m,cnt;
    24 int p[maxe];
    25 int dis[maxv];
    26 int vis[maxv];
    27 void add(int u, int v, int w)
    28 {
    29     cnt++;
    30     edge[cnt].v = v;
    31     edge[cnt].w = w;
    32     edge[cnt].next = p[u];
    33     p[u] = cnt;
    34 }
    35 
    36 void dijstra(int s)
    37 {
    38     priority_queue<struct node1> que;
    39     for(int i = 1; i <= n; i++)
    40         dis[i] = INF;
    41     memset(vis,0,sizeof(vis));
    42 
    43     dis[s] = 0;
    44     que.push((struct node1){s,dis[s]});
    45     for(int i = 0; i < n; i++)
    46     {
    47         while(!que.empty() && vis[que.top().v])
    48             que.pop();
    49         if(que.empty()) break;
    50 
    51         node1 tmp = que.top();
    52         que.pop();
    53         vis[tmp.v] = 1;
    54         for(int j = p[tmp.v]; j; j = edge[j].next)
    55         {
    56             if((dis[edge[j].v] > dis[tmp.v] + edge[j].w) && !vis[edge[j].v])
    57             {
    58                 dis[edge[j].v] = dis[tmp.v] + edge[j].w;
    59                 que.push((struct node1){edge[j].v,dis[edge[j].v]});
    60             }
    61         }
    62     }
    63 }
    64 
    65 int main()
    66 {
    67     while(~scanf("%d %d",&n,&m))
    68     {
    69         int u,v,w;
    70         memset(p,0,sizeof(p));
    71         cnt = 0;
    72         for(int i = 0; i < m; i++)
    73         {
    74             scanf("%d %d %d",&u,&v,&w);
    75             add(u,v,w);
    76         }
    77         dijstra(1);
    78         printf("%d
    ",dis[n]);
    79 
    80     }
    81     return 0;
    82 }
    View Code

     看discuss里面也可以用SPFA+stack,可能用stack效率高一点吧。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 #include<stack>
     5 using namespace std;
     6 
     7 const int INF = 0x3f3f3f3f;
     8 const int maxv = 30100;
     9 const int maxe = 150100;
    10 
    11 struct node
    12 {
    13     int v,w;
    14     int next;
    15 }edge[maxe];
    16 int n,m,cnt;
    17 int p[maxe];
    18 int dis[maxv],instack[maxv];
    19 void add(int u, int v, int w)
    20 {
    21     cnt++;
    22     edge[cnt].v = v;
    23     edge[cnt].w = w;
    24     edge[cnt].next = p[u];
    25     p[u] = cnt;
    26 }
    27 
    28 void SPFA(int s)
    29 {
    30     stack<int>st;
    31     for(int i = 1; i <= n; i++)
    32         dis[i] = INF;
    33     memset(instack,0,sizeof(instack));
    34     dis[s] = 0;
    35     st.push(s);
    36     instack[s] = 1;
    37     while(!st.empty())
    38     {
    39         int u = st.top();
    40         st.pop();
    41         instack[u] = 0;
    42 
    43         for(int i = p[u]; i; i = edge[i].next)
    44         {
    45             if(dis[edge[i].v] > dis[u] + edge[i].w)
    46             {
    47                 dis[edge[i].v] = dis[u] + edge[i].w;
    48                 if(!instack[edge[i].v])
    49                 {
    50                     st.push(edge[i].v);
    51                     instack[edge[i].v] = 1;
    52                 }
    53             }
    54         }
    55     }
    56 }
    57 
    58 int main()
    59 {
    60     while(~scanf("%d %d",&n,&m))
    61     {
    62         cnt = 0;
    63         memset(p,0,sizeof(p));
    64         int u,v,w;
    65         for(int i = 0; i < m; i++)
    66         {
    67             scanf("%d %d %d",&u,&v,&w);
    68             add(u,v,w);
    69         }
    70         SPFA(1);
    71         printf("%d
    ",dis[n]);
    72     }
    73     return 0;
    74 }
    View Code
  • 相关阅读:
    java 线程之间的协作 wait()与notifyAll()
    加密web.config中的邮件配置mailSettings
    TCP编程,Socket通讯
    jQuery插件学习笔记
    抹掉Scala的糖衣(14) -- Update Method
    UVA 12034 Race (递推神马的)
    struts2 命名空间 namespace 学习
    Vim -&gt; 移动光标
    【跟我一步一步学Struts2】——Struts2工作流程
    Python中sort以及sorted函数初探
  • 原文地址:https://www.cnblogs.com/LK1994/p/3438317.html
Copyright © 2020-2023  润新知