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 }
看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 }