很久以前还有过一篇floyd和dijkstra的东西虽然写得丑也放上来吧
多源最短路,k要放在外面。
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);
用优先队列维护,不能有负权边。
memset(dist,0x3f,sizeof(dist));
dist[1]=0; q.push(PLI(0,1)); //priority_queue
while(!q.empty())
{
int u=q.top().second;
LL di=q.top().first;
q.pop();
if(di>dist[u]) continue;
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i].first,w=G[u][i].second;
if(dist[v]>dist[u]+w)
{
dist[v]=dist[u]+w;
q.push(PLI(dist[v],v));
}
}
}
用队列存储可以松弛其他点的点,代码自行参考下面代码建完图之后的部分。
还可以用dfs来写,求负环会比较好。
void dfs(int u,double x)
{
vis[u]=true;
for(node *p=head[u];p!=NULL;p=p->nxt)
{
int v=p->v;
double w=p->w-x;
if(dist[v]>dist[u]+w)
{
if(vis[v]) { f=true; break; }
dist[v]=dist[u]+w;
dfs(v,x);
}
}
vis[u]=false;
}
如果一个系统由n个变量和m个约束条件组成,形成m个形如 a i − a j ≤ k a_i-a_j≤k ai−aj≤k的不等式( i , j ∈ [ 1 , n ] i,j∈[1,n] i,j∈[1,n],k为常数),则称其为差分约束系统(system of difference constraints)。亦即,差分约束系统是求解关于一组变量的特殊不等式组的方法。
求解差分约束系统,可以转化成图论的单源最短路径(或最长路径)问题。
观察不等式 a i − a j ≤ k a_i-a_j≤k ai−aj≤k,可以成为 a i ≤ k + a j a_i≤k+a_j ai≤k+aj,长得就像求最短路时的松弛操作。所以对于每个不等式,可以建一条从j到i的有向边,边权为k。
如果符号不是≤,那就转化啊。
a i − a j ≥ k a_i-a_j \ge k ai−aj≥k可以转化为 a j − a i ≤ − k a_j-a_i \le -k aj−ai≤−k;
a i − a j < k a_i-a_j \lt k ai−aj<k可以转化为 a i − a j ≤ k − 1 a_i-a_j \le k-1 ai−aj≤k−1;
a i − a j = k a_i-a_j = k ai−aj=k可以转化为 a i − a j ≤ k , a i − a j ≥ k a_i-a_j \le k,a_i-a_j \ge k ai−aj≤k,ai−aj≥k(然后再继续转化一下即可)。
如果要求最大值,那么转化为≤,跑最短路;如果要求最小值,那么转化为≥,跑最长路。
跑最短路时,如果发现负环,就说明题目给的信息矛盾,不等式组无解;
如果到达不了,就说明有变量没有被约束。
以下是bzoj1731的代码(就当一个写得比较丑的板子):
#include
#include
#include
#include
#include
#define maxn 1005
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
struct node { int v,w; };
int n,ml,md,dist[maxn],cnt[maxn];
bool inq[maxn];
vector<node> G[maxn];
queue<int> q;
int main()
{
scanf("%d%d%d",&n,&ml,&md);
for(int i=2;i<=n;i++)
{
node p;
p.v=i-1,p.w=0;
G[i].push_back(p);
}
for(int i=1;i<=ml;i++)
{
int u; node p;
scanf("%d%d%d",&u,&p.v,&p.w);
G[u].push_back(p);
}
for(int i=1;i<=md;i++)
{
int u; node p;
scanf("%d%d%d",&p.v,&u,&p.w);
p.w=-p.w;
G[u].push_back(p);
}
memset(dist,0x3f,sizeof(dist));
dist[1]=0,inq[1]=true,cnt[1]=1;
q.push(1);
while(!q.empty())
{
int u=q.front();q.pop();
inq[u]=false;
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i].v,d=G[u][i].w;
if(dist[v]>dist[u]+d)
{
dist[v]=dist[u]+d;
if(!inq[v])
{
cnt[v]++;
q.push(v);inq[v]=true;
if(cnt[v]>=n) { printf("-1\n"); return 0; }
}
}
}
}
printf("%d\n",dist[n]==INF?-2:dist[n]);
}
题目:bzoj1731