注意有图的连通性的坑,构造超级原点
不等式求最小值,造 A-B>=C ---》 B->A=C的边 ,求最长路。
若为A-B>C的形式 构造为A-B>=C+1 从而造边
可以判正环
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <queue>
#include <vector>
#include <cmath>
#include <stack>
using namespace std;
const int maxn=10005;
typedef long long ll;
vector<pair<int ,ll > > vec[maxn];
int vis[maxn];
int info[maxn];
ll dis[maxn];
const ll inf=0x3f3f3f3f3f3f3f3f;
int n,m;
int spfa(int st)
{
memset(info,0,sizeof(info));
memset(vis,0,sizeof(vis));
for(int i=0;i<=n;i++)
{
vis[i]=0,dis[i]=-inf,info[i]=0;
}
vis[st]=1,dis[st]=0,info[st]=1;
deque<int>q;
q.push_front(st);
int u;
while(!q.empty())
{
u=q.front();
q.pop_front();
vis[u]=0;
for(int i=0; i<vec[u].size(); i++)
{
int v=vec[u][i].first;
ll w=vec[u][i].second;
if( dis[v] < w+dis[u] )
{
dis[v]=w+dis[u];
if(!vis[v])
{
info[v]++;
vis[v]=1;
if(!q.empty()&&dis[v]<dis[q.front()])
q.push_back(v);
else
q.push_front(v);
if(info[v]>n)
{
return 0;
}
}
}
}
}
return 1;
}
int main()
{
while(~scanf("%d%d",&n,&m) )
{
for(int i=0; i<=maxn; i++)
vec[i].clear();
int u,v;
ll w;
///造边
/*
for(int i=1;i<=n;i++)
{
scanf("%lld",&w);
vec[i-1].push_back( make_pair(i,0) );
vec[i].push_back(make_pair(i-1,-w));
vec[0].push_back(make_pair(i,0));
}
for(int i=1;i<=m;i++)
{
scanf("%d%d%lld",&u,&v,&w);
vec[u-1].push_back(make_pair(v,w));
}*/
if(spfa(0))
{
printf("%lld\n",dis[n]);
}
else
{
puts("Bad Estimations");
}
}
return 0;
}
不等式求最大值,造A-B《=C的不等式 构造B->A ==C的边
若为A-B<C 构造A-B<=C-1 的边即可。
可以判负环#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <queue>
#include <vector>
#include <cmath>
#include <stack>
using namespace std;
const int maxn=100005;
vector<pair<int ,double > > vec[maxn];
int vis[maxn];
int info[maxn];
typedef long long ll;
lll dis[maxn];
const ll inf=0x3f3f3f3f3f3f3f3f;
int n,m;
int spfa()
{
memset(info,0,sizeof(info));
memset(vis,0,sizeof(vis));
for(int i=0;i<=n;i++)
{
dis[i]=inf;
}
vis[0]=1,dis[0]=0,info[0]=1;
stack<int> s;
s.push(0);
int u;
while(!s.empty())
{
u=s.top();
s.pop();
vis[u]=0;
for(int i=0;i<vec[u].size();i++)
{
int v=vec[u][i].first;
ll w=vec[u][i].second;
if( dis[v]>w+dis[u] )
{
dis[v]=w+dis[u];
if(!vis[v])
{
info[v]++;
vis[v]=1;
s.push(v);
if(info[v]>n) ///注意负环判断位置
{
return 0;
}
}
}
}
}
return 1;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
for(int i=0;i<=maxn;i++)
vec[i].clear();
///造边 注意造超级原点,即为 0->所有边为 0
if(spfa(0))
{
printf("YES\n");
}
else
printf("NO\n");
}
}