这道题很是给力啊,,spfa+stack一下AC了,,有点小激动,,,,,
大自的说一下题意啊,,,就是班长分蜡烛,让你求该班长和他那班的一个同学所分蜡烛差的最大值,,下面介绍一下建图思想,,假设第i个同学有a[i]个蜡烛,设dist[i]为第i个同学相对于第一个同学的蜡烛数,d[i]=a[i]-a[i];d[1]=0;
题目让输入的A B C表示 a[B]-a[A]<=c 可以表示为 ( a[B]-a[1]) -(a[A]-a[1]) <=c 即 dis[B]-dis[A]<=c 题目让求最大值即求以1为源点的最短路问题。
下面是这两天我的得出得结论。。仅供参考。。。
如果求未知数的最大值,那么按小于等于建图后求最短路即可。(因为求最短路是由无穷向下约束而得到的,所以得到的一定是最大值)。
如果求未知数的最小值,那么按小于等于建图后求最长路即可。
注意所有数据的关系,不能漏掉关系,还有与附加源点的关系。
如果是按大于等于建图:
求最大值,建图后求最长路;
求最小值,建图后求最短路。
因为大于等于建图后,相当于未知数都*-1了,所以求出结果后需要*-1。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<stack>
#define N 30010
#define M 999999999
using namespace std;
int n,m,size;
struct Node{ int to,len,next;
}node[N*10];
bool visit[N];
int adj[N];
int dist[N];
void init()
{ size=0;
for(int i=1;i<=n;++i)
{visit[i]=false;
adj[i]=-1;
dist[i]=M;
}
}
void Add(int a,int b,int c)
{ node[size].to=b;
node[size].len=c;
node[size].next=adj[a];
adj[a]=size++;
}
void spfa()
{ stack<int> Q;
dist[1]=0,visit[1]=true;
Q.push(1);
while(!Q.empty())
{ int u=Q.top();
Q.pop();
visit[u]=false;
for(int i=adj[u];i!=-1;i=node[i].next)
{ int v=node[i].to;
int l=node[i].len;
if(dist[v]>dist[u]+l)
{ dist[v]=dist[u]+l;
if(!visit[v])
{ Q.push(v);
visit[v]=true;
}
}
}
}
printf("%d\n",dist[n]);
}
int main()
{ while(scanf("%d%d",&n,&m)!=EOF)
{ init();
int a,b,c;
for(int i=1;i<=m;++i)
{ scanf("%d%d%d",&a,&b,&c);
Add(a,b,c);
}
spfa();
}return 0;
}
优先队列写法:
#include<iostream>
#include<cstdio>
#include<queue>
#include<stack>
#define N 30010
#define M 999999999
using namespace std;
int n,m,size;
struct Node{ int to,len,next;
}node[N*10];
bool visit[N];
int adj[N];
int dist[N];
void init()
{ size=0;
for(int i=1;i<=n;++i)
{visit[i]=false;
adj[i]=-1;
dist[i]=M;
}
}
void Add(int a,int b,int c)
{ node[size].to=b;
node[size].len=c;
node[size].next=adj[a];
adj[a]=size++;
}
struct cmp
{ bool operator() (const int &a, const int &b)
{ return dist[a] > dist[b]; }
};
priority_queue<int ,vector<int>,cmp> Q;
void dijstra()
{
dist[1]=0,visit[1]=true;
Q.push(1);
while(!Q.empty())
{ int u=Q.top();
Q.pop();
visit[u]=false;
for(int i=adj[u];i!=-1;i=node[i].next)
{ int v=node[i].to;
int l=node[i].len;
if(dist[v]>dist[u]+l)
{ dist[v]=dist[u]+l;
if(!visit[v])
{ Q.push(v);
visit[v]=true;
}
}
}
}
printf("%d\n",dist[n]);
}
/*void spfa()
{ stack<int> Q;
dist[1]=0,visit[1]=true;
Q.push(1);
while(!Q.empty())
{ int u=Q.top();
Q.pop();
visit[u]=false;
for(int i=adj[u];i!=-1;i=node[i].next)
{ int v=node[i].to;
int l=node[i].len;
if(dist[v]>dist[u]+l)
{ dist[v]=dist[u]+l;
if(!visit[v])
{ Q.push(v);
visit[v]=true;
}
}
}
}
printf("%d\n",dist[n]);
} */
int main()
{ while(scanf("%d%d",&n,&m)!=EOF)
{ init();
int a,b,c;
for(int i=1;i<=m;++i)
{ scanf("%d%d%d",&a,&b,&c);
Add(a,b,c);
}
//spfa();
dijstra();
}return 0;
}