服务器储存信息问题 差分约束

下面是题面。

【问题描述】

Byteland 王国准备在各服务器间建立大型网络并提供多种服务。

网络由 n 台服务器组成,用双向的线连接。两台服务器之间最多只能有一条线直接连接,同时,每台服务器最多只能和 10 台服务器直接连接,但是任意两台服务器间必然存在一条路径将它们连接在一起。每条传输线都有一个固定传输的速度。δ (v , w) 表示服务器 v 和 w 之间的最短路径长度,且对任意的 V 有δ (V , V)=0 。

有些服务器比别的服务器提供更多的服务,它们的重要程度要高一些。我们用 r(v) 表示服务器 V 的重要程度 (rank) 。 rank 越高的服务器越重要。

每台服务器都会存储它附近的服务器的信息。当然,不是所有服务器的信息都存,只有感兴趣的服务器信息才会被存储。服务器 V 对服务器 w 感兴趣是指,不存在服务器 U 满足, r(U)>r(W) 且δ (V , U)<= δ (V ,W) 。

举个例子来说,所有具有最高 rank 的服务器都会被别的服务器感兴趣。如果 V 是一台具有最高 rank 的服务器,由于δ (V , V) =0 ,所以 V 只对具有最高 rank 的服务器感兴趣。我们定义 B(V) 为 V 感兴趣的服务器的集合。

我们希望计算所有服务器储存的信息量,即所有服务器的| B(V) |之和。 Byteland 王国并不希望存储大量的数据,所以所有服务器存储的数据量 ( | B(V) |之和 ) 不会超过 30n 。

你的任务是写一个程序,读入 Byteland 王国的网络分布,计算所有服务器存储的数据量。

【输入】

第一行两个整数 n 和 m , (1 ≤ n ≤ 30 000 , 1 ≤ m ≤ 5n) 。 n 表示服务器的数量, m 表示传输线的数量。

接下来 n 行,每行一个整数,第 i 行的整数为 r(i)(1 ≤ r(i) ≤ 10) ,表示第 i 台服务器的rank 。

接下来 m 行,每行表示各条传输线的信息,包含三个整数 a , b , t(1 ≤ t ≤ 1000 , l ≤ a , b ≤ n , a ≠ b) 。 a 和 b 是传输线所连接的两台服务器的编号, t 是传输线的长度。

【输出】

一个整数,表示所有服务器存储的数据总量,即| B(V) |之和。

【样例】

Servers.in

4 3
2
3
1
1
1 4 30
2 3 20
3 4 20

servers . out

9

注: B(1)={1 , 2} , B(2)={2} , B(3)={2 , 3} , B(4)={1 , 2 , 3 , 4} 。

我们发现暴力很好想也很好写,做n遍SPFA,再按rank把点扫一遍就好了,复杂度大概是平方级的。

那么正解应该是在这上面的优化。

注意到最终的答案不会超过30n,但是点对有n^2个?所以说这应该是一个剪枝点。

同时发现rank<=10?

有一个非常重要的数据,点x到rank为i的点集的最短路径。有了这个可以方便很多计算,这也是rank很小的原因之一。

于是我们把它记为 Far[i][x];

然后我们可以扩展一下它的含义:"x到rank为i的点集的最短路径"可以换成"x到rank大于等于i的点集的最短路径"。

这样我们一次比较u和v,就只要看一下:far(u,v)<Far[rank[v]+1][u];(far就是δ);

那么接下来来剪上面那个枝。

现在我们以w为起点,找到了一个点v,而v不关心w;

不满足关系的条件为: far(w,v) >= Far[rank[w]+1][v];

若我们把v扔进队列进行接下来的SPFA松弛,假设v松弛到u;

由SPFA性质得此时 far(u,w)=far(w,v)+far(v,u);

而 far(w,v) >= Far[rank[w]+1][v];

所以 far(w,u)

=far(u,v)+far(v,w)

>=far(u,v)+Far[rank[w]+1][v]

>=Far[rank[w]+1][u];

所以此时u也是不对w感兴趣的点。

这告诉我们:SPFA到一个不满足条件的点,你大可不必将它放进队列里。

因为题目告诉我们答案不超过30n,所以SPFA的复杂度均摊下来很小。

于是你切完这题后就可以跟别人说:"啊?我做了n遍SPFA就过了啊!"

听上去似乎有那么点道理... ...

#include    <iostream>
#include    <cstdio>
#include    <cstdlib>
#include    <algorithm>
#include    <vector>
#include    <cstring>
#include    <queue>
#define LL long long int
#define ls (x << 1)
#define rs (x << 1 | 1)
#define rank bobo
using namespace std;

const int N = 30010;
const int M = N*10;
struct Data{int to,next;}Edge[N];
struct Node{int to,val,next;}E[M];
int n,m,Head[12],Tot,head[N],tot,rank[N];
int Ans,Far[12][N],far[N],In[N],vis[N];

int gi()
{
  int x=0,res=1;char ch=getchar();
  while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)res*=-1;ch=getchar();}
  while(ch<=‘9‘&&ch>=‘0‘)x=x*10+ch-48,ch=getchar();
  return x*res;
}

inline void Link(int u,int v)
{
  Edge[++Tot]=(Data){v,Head[u]};
  Head[u]=Tot;
}

inline void link(int u,int v,int c)
{
  E[++tot]=(Node){v,c,head[u]};
  head[u]=tot;
}

inline void SPFA1(int p)
{
  memset(Far[p],127/3,sizeof(Far[p]));
  memset(In,0,sizeof(In));
  queue<int>Q;
  for(int e=Head[p];e;e=Edge[e].next){
    Far[p][Edge[e].to]=0;
    Q.push(Edge[e].to);
  }
  while(!Q.empty()){
    int x=Q.front();Q.pop();In[x]=0;
    for(int e=head[x];e;e=E[e].next){
      int y=E[e].to;
      if(Far[p][x]+E[e].val<Far[p][y]){
	Far[p][y]=Far[p][x]+E[e].val;
	if(!In[y])In[y]=1,Q.push(y);
      }
    }
  }
}

inline void TS(int p)
{
  for(int x=1;x<=n;++x)
    if(Far[p][x]>Far[p+1][x])
      Far[p][x]=Far[p+1][x];
}

inline void SPFA(int p)
{
  memset(far,0x3f,sizeof(far));
  memset(vis,0,sizeof(vis));
  far[p]=0;In[p]=1;
  queue<int>Q;Q.push(p);
  while(!Q.empty()){
    int x=Q.front();Q.pop();In[x]=0;
    if(!vis[x])Ans+=(vis[x]=1);
    for(int e=head[x];e;e=E[e].next){
      int y=E[e].to;
      if(far[y]>far[x]+E[e].val){
	far[y]=far[x]+E[e].val;
	if(!In[y] && far[y]<Far[rank[p]+1][y])
	  Q.push(y),In[y]=1;
      }
    }
  }
}

int main()
{
  n=gi();m=gi();
  for(int i=1;i<=n;++i){
    rank[i]=gi();Link(rank[i],i);
  }
  for(int i=1;i<=m;++i){
    int u=gi(),v=gi(),t=gi();
    link(u,v,t);link(v,u,t);
  }
  for(int i=1;i<=10;++i)SPFA1(i);
  for(int i=9;i;--i)TS(i);
  for(int i=1;i<=n;++i)SPFA(i);
  printf("%d\n",Ans);
  return 0;
}
时间: 2024-10-28 15:19:37

服务器储存信息问题 差分约束的相关文章

POJ 2983 Is the Information Reliable? 信息可靠吗 (差分约束,spfa)

题意:有n个站排成一列,针对每个站的位置与距离关系,现有多个约束条件,约束条件分两种:(1)确定的.明确说明站a距离站b多少个单位距离.(2)不确定的.只知道a在b的左边至少1个单位距离.  根据已知条件,问有没有冲突?不冲突则输出reliable. 思路: 第2种条件比较好确定,如果知道如何用最短路解差分约束的话. 问题在第1种,明确地说明了距离,怎么办?拆成两条式子,比如 dis(a,b)=c,那么可以写成 b-a>=c ,b-a<=c 这样,只要满足这两个条件,原来明确说明的距离也会成立

BZOJ 1202: [HNOI2005]狡猾的商人( 差分约束 )

好像很多人用并查集写的... 前缀和, 则 sumt - sums-1 = v, 拆成2条 : sumt ≤ sums-1 + v, sums-1 ≤ sumt - v 就是一个差分约束, 建图跑SPFA.. 想起之前codeVS某场月赛T1有些人用带权并查集..然而我是差分约束水过去的... ------------------------------------------------------------------------------ #include<cstdio> #incl

bzoj3436: 小K的农场(差分约束)

3436: 小K的农场 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1575  Solved: 690[Submit][Status][Discuss] Description 背景 小K是个特么喜欢玩MC的孩纸... 描述 小K在MC里面建立很多很多的农场,总共n个,以至于他自己都忘记了每个农场中种植作物的具体数量了,他只记得 一些含糊的信息(共m个),以下列三种形式描述:农场a比农场b至少多种植了c个单位的作物,农场a比农场b至多 多种植了

ZOJ2770,火烧连营,差分约束

差分约束关键在于明白为什么可以转化为三角不等式. 还有对于不等式   Xi - Xj <= c,要转化为边<Vj, Vi>. 这ZOJ2770自己分析的还是挺正确的. 具体分析不写了,附个代码= =  加注释可能稍微比较乱. #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #includ

【差分约束】Layout

Layout TimeLimit: 1000MS   MemoryLimit: 65536K       Description Like everyone else, cows like to stand close to their friends when queuing for feed. FJ has N (2 <= N <= 1,000) cows numbered 1..N standing along a straight line waiting for feed. The

【转载】夜深人静写算法(四)——差分约束

[转载]夜深人静写算法(四) - 差分约束  目录     一.引例       1.一类不等式组的解   二.最短路       1.Dijkstra       2.图的存储       3.链式前向星       4.Dijkstra + 优先队列       5.Bellman-Ford       6.SPFA       7.Floyd-Warshall   三.差分约束        1.数形结合        2.三角不等式        3.解的存在性        4.最大值

【差分约束】

这里有一大堆不等式或者等式形成的限制条件,题目通常会问问你是否存在合法方案或者让你求出合法方案.----------差分约束 ·前言:       一个概括的定义是,一些不等式组可以视作一个差分约束系统.简单而言,就是给出许多不等式,然后我们需要给每个未知数填上值,使它们满足所有给出的关于它们的不等式--这正是这类问题的求解过程.由于这一过程类似于最短路算法中的松弛操作,因此解决差分约束问题成了最短路算法的一个美妙而重要用途. ·一个例题        这里呢有一个长度为n的序列,现在给出m条信

Luogu - 1993 小K的农场 【差分约束】

题目描述 小 K 在 Minecraft 里面建立很多很多的农场,总共 n 个,以至于他自己都忘记了每个 农场中种植作物的具体数量了,他只记得一些含糊的信息(共 m 个),以下列三种形式描 述: 农场 a 比农场 b 至少多种植了 c 个单位的作物. 农场 a 比农场 b 至多多种植了 c 个单位的作物. 农场 a 与农场 b 种植的作物数一样多. 但是,由于小 K 的记忆有些偏差,所以他想要知道存不存在一种情况,使得农场的种 植作物数量与他记忆中的所有信息吻合. 输入输出格式 输入格式: 从

P1993 小K的农场 &amp;&amp; 差分约束

首先第一篇讨论的是差分约束系统解的存在 差分约束系统是有 \(n\) 个变量及 \(m\) 个(如 \(x_{i} - x_{j} \leq a_{k}\) )关系组成的系统 差分约束解的求解可以转化为图中最短路的求解问题 对一个标准的差分约束式, 我们可以如下连边\[x_{i} - x_{j} \leq a_{k}\ \Rightarrow \ V(j\ ,\ i), w[j,i] = a[k]\] 对于一个不是那么标准的差分约数式, 我们可以做如下变形:\[x_{i} - x_{j} \ge