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\n",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\n",dis[n]);
72     }
73     return 0;
74 }
View Code

 

 

posted on 2013-11-22 22:01  straw_berry  阅读(329)  评论(0编辑  收藏  举报