poj 2983 中等的差分约束
2013-12-14 20:05
375 查看
对于差分约束题目的关键在于怎么找到问题约束的条件,这也是难点
对于本题主要有两个条件
:
1. 边长确定,即xi - xj = b; 可以转化成 xi -
xj <= b 和 xi - xj >=b (即 xj - xi <= -b).
2. 边长不定,xi - xj >= 1; 可以转化成 xj - xi <= -1;
再通过这两个条件建图 , 然后再用SPFA算法就行了 , 由于我们所建的图不一定是一个连通图 ,
所以我们加一个源点 , 这个源点到其他每一个点都有一条边权为1的边 ;
或则用并查集来区分这个图的基图有多个个连通分量 ,
我们然后再分别对每个连通分量调用一次SPFA
代码:
#include
#include
#include
#include
using namespace std;
#define maxn 1010
#define INF 0xfffffff
int dist[maxn] , n , m , k;
int p[maxn];
struct node
{
int
to;
int w;
int
next;
}edge[201005];
int head[maxn];
void init()
{
memset(head
, -1 , sizeof(head));
for(int i =
1; i <= n; i++)
p[i] =
i;
}
int SPFA(int xy)
{
int i ,
pre[maxn] , vis[maxn];
queueq1;
for(i = 0; i
<= n; i++)
dist[i] =
INF;
memset(vis ,
0 , sizeof(vis));
memset(pre ,
0 , sizeof(pre));
vis[xy] +=
1;
dist[xy] =
0;
q1.push(xy);
while(!q1.empty())
{
int u =
q1.front(); q1.pop();
pre[u] =
0;
//cout<<u<<endl;
for(i =
head[u]; i != -1 ; i = edge[i].next)
{
//cout<<i<<endl;
int x =
edge[i].to;
if(dist[x]
> dist[u]+edge[i].w)
{
dist[x] =
dist[u]+edge[i].w;
if(!pre[x])
{
pre[x] = 1 ,
q1.push(x);
if(++vis[x]
> (n+1))
{
return
0;
}
}
对于本题主要有两个条件
:
1. 边长确定,即xi - xj = b; 可以转化成 xi -
xj <= b 和 xi - xj >=b (即 xj - xi <= -b).
2. 边长不定,xi - xj >= 1; 可以转化成 xj - xi <= -1;
再通过这两个条件建图 , 然后再用SPFA算法就行了 , 由于我们所建的图不一定是一个连通图 ,
所以我们加一个源点 , 这个源点到其他每一个点都有一条边权为1的边 ;
或则用并查集来区分这个图的基图有多个个连通分量 ,
我们然后再分别对每个连通分量调用一次SPFA
代码:
#include
#include
#include
#include
using namespace std;
#define maxn 1010
#define INF 0xfffffff
int dist[maxn] , n , m , k;
int p[maxn];
struct node
{
int
to;
int w;
int
next;
}edge[201005];
int head[maxn];
void init()
{
memset(head
, -1 , sizeof(head));
for(int i =
1; i <= n; i++)
p[i] =
i;
}
int SPFA(int xy)
{
int i ,
pre[maxn] , vis[maxn];
queueq1;
for(i = 0; i
<= n; i++)
dist[i] =
INF;
memset(vis ,
0 , sizeof(vis));
memset(pre ,
0 , sizeof(pre));
vis[xy] +=
1;
dist[xy] =
0;
q1.push(xy);
while(!q1.empty())
{
int u =
q1.front(); q1.pop();
pre[u] =
0;
//cout<<u<<endl;
for(i =
head[u]; i != -1 ; i = edge[i].next)
{
//cout<<i<<endl;
int x =
edge[i].to;
if(dist[x]
> dist[u]+edge[i].w)
{
dist[x] =
dist[u]+edge[i].w;
if(!pre[x])
{
pre[x] = 1 ,
q1.push(x);
if(++vis[x]
> (n+1))
{
return
0;
}
}
相关文章推荐
- zoj 2770 差分约束的应用及其原理
- poj 1734 Floyd算求有向图的最小环
- poj 2570 floyd算法+二进制的应用
- poj 3249 DAG上的最短路问题
- poj 2449 求第k最短路 A* + SPFA
- poj 2253 dijkstra
- poj 1125 简单的floyd应…
- poj 3268 简单的SPFA算法运用
- poj 2387 简单的dijkstra运用
- poj 1135 有点弯的最短路运用
- poj 1079 判断最…
- poj 1258 简单的prim算法运用
- poj 2031 简单的kruskal算法运用
- poj1823,3667
- poj 1465 一题非常经典的bfs题
- hdu 1026 简单的bfs
- hdu1728 很有难度的bfs…
- poj 1733 并查集+偏移向…
- poj 1182 并查集经典题…
- poj 1611 并查集训练