题意:
有一包糖果要分给n个学生,对于输入数据u v w代表学生v得到的糖果数比学生u得到的糖果数 至多可以多出w个。
问满足条件的情况下,学生n比学生1至多可以多出多少个糖果。
思路:
很显然的差分约束方程求解问题。
先根据u v w构造差分方程:d[ v ]-d[ u ]<=w;
再用该方程建图:addedge(u,v,w):建立一条从u出发到v的权值为w的单向边。
然后进行spfa找出最短路即可。
但是这题卡就卡在数据比较怪,SPFA如果用队列则超时,用STACK才能AC。
#include<iostream> #include<vector> #include<string> #include<queue> #include<algorithm> #define llong long long #define Min(a,b) (a<b?a:b) #define Max(a,b) (a>b?a:b) #define Abs(a) ((a)>0?(a):-(a)) #define Mod(a,b) (((a)-1+(b))%(b)+1) using namespace std; const int N=30005; const int M=150005; const int inf=1000000000; int n,m; struct { int v,next,w; }edge[M]; int edgehead[N]; bool vis[N]; int d[N]; int k; int stack[N]; int sp; void addedge(int u,int v,int w) { edge[k].v=v; edge[k].w=w; edge[k].next=edgehead[u]; edgehead[u]=k++; } void spfa() { memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) d[i]=inf; d[1]=0; vis[1]=true; sp=0; stack[sp++]=1; while(sp) { int now=stack[--sp]; vis[now]=false; for(int i=edgehead[now];i;i=edge[i].next) { int v=edge[i].v; int w=edge[i].w; if(d[v]>d[now]+w) { d[v]=d[now]+w; if(!vis[v]) { vis[v]=true; stack[sp++]=v; } } } } printf("%d\n",d[n]); } int main() { scanf("%d%d",&n,&m); int u,v,w; k=1; for(int i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&w); addedge(u,v,w); } spfa(); return 0; }
以下的dijstra+heap始终WA,不明白为什么,根据discuss说用队列返回的WA实际上很可能是TLE。
查了不少博客,有用priority_queue AC的,但是他们的priority_queue和我的
priority_queue<int,vector<int>,cmp> que;不一样,或者是我的queue耗时比较多吧。
蛋疼了,先到这。
#include<iostream> #include<vector> #include<string> #include<queue> #include<algorithm> #define llong long long #define Min(a,b) (a<b?a:b) #define Max(a,b) (a>b?a:b) #define Abs(a) ((a)>0?(a):-(a)) #define Mod(a,b) (((a)-1+(b))%(b)+1) using namespace std; const int N=30005; const int M=150005; const int inf=1000000000; int n,m; struct { int v,next,w; }edge[M]; int edgehead[N]; bool vis[N]; int d[N]; int k; void addedge(int u,int v,int w) { edge[k].v=v; edge[k].w=w; edge[k].next=edgehead[u]; edgehead[u]=k++; } struct cmp { bool operator()(const int a,const int b) { return d[a]>d[b]; } }; void dijstra() { priority_queue<int,vector<int>,cmp> que; memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) d[i]=inf; d[1]=0; que.push(1); while(!que.empty()) { int now=que.top(); que.pop(); if(vis[now]) continue; vis[now]=true; for(int i=edgehead[now];i;i=edge[i].next) { int v=edge[i].v; int w=edge[i].w; if(!vis[v]&&d[v]>d[now]+w) { d[v]=d[now]+w; que.push(v); } } } printf("%d\n",d[n]); } int main() { scanf("%d%d",&n,&m); int u,v,w; k=1; for(int i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&w); addedge(u,v,w); } dijstra(); return 0; }