题意:N个点,分别有属于自己的N个busyness(简称b),两点间若有边,则边权为(ub-vb)^3。Q个查询,问从点1到该点的距离为多少。

分析:既然是差的三次方,那么可能有负边权的存在,自然有可能出现负环。第一次用Dijkstra做,没多想,样例过了就去交了,结果肯定是WA了。之后加入了对负环的判断。很明显,如果在SPFA的算法过程中,若点u进出队列的次数达到N(N次松弛操作),那么u肯定在负环中。此外,u的邻接点v的距离dist[v]也必然<3,因为dsit[u]可以取到一个极小值。通过dfs函数给这些邻接点也加上标记。最后查询时,若点v不可到达,距离小于3或被标记,都是不合法的情况。

#include<iostream>
#include<cstring>
#include<stdio.h>
#include<vector>
#include<string>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
typedef int LL;
const int MAXN = ;
const int MAXM = MAXN * MAXN;
const int INF = 0x3f3f3f3f;
queue<int>q;
int N,M;
struct Edge{
int v,next;
int w;
}; struct Spfa
{
int N,M;
bool inq[MAXN];
int dp[MAXN],cnt[MAXN];
int pre[MAXN];
int head[MAXN],tot;
int dis[MAXN];
bool incir[MAXN];
Edge edge[MAXM]; void init(int n){
N = n;
tot = ;
memset(head,-,sizeof(head));
memset(cnt,,sizeof(cnt));
} void Addedge(int u,int v,int w){
edge[tot].v = v;
edge[tot].w = w;
edge[tot].next = head[u];
head[u] = tot++;
} void dfs(int pos){
incir[pos] = true;
for (int i = head[pos] ; i != - ; i = edge[i].next){
int v = edge[i].v;
if (!incir[v])
dfs(v);
}
} void spfa(int s){
memset(incir,false,sizeof(incir));
memset(inq,false,sizeof(inq));
for (int i = ; i <= N ; i++) dis[i] = INF;
while (!q.empty()) q.pop();
q.push(s);
dis[s] = ;
cnt[s] = ;
inq[s] = true;
while (!q.empty()){
int u = q.front(); q.pop();
inq[u] = false;
for (int i = head[u] ; i != - ; i = edge[i].next){
int v = edge[i].v;
if (incir[v]) continue;
if (dis[v] > dis[u] + edge[i].w){
dis[v] = dis[u] + edge[i].w;
if (!inq[v]){
inq[v] = true;
cnt[v]++;
q.push(v);
if (cnt[v] >= N) dfs(v);
}
}
}
}
}
}G; LL dist(LL a,LL b){
LL t = b-a;
return t*t*t;
} LL p[MAXN]; #define LOCAL
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int N,M,S,T,u,v,q,cas=;
LL tmp,b;
scanf("%d",&T);
while(T--){
scanf("%d",&N);
G.init(N);
for(int i=;i<=N;++i){
scanf("%d",&p[i]);
}
scanf("%d",&M);
for(int i=;i<=M;++i){
scanf("%d%d",&u,&v);
G.Addedge(u,v,dist(p[u],p[v]));
}
G.spfa();
scanf("%d",&q);
printf("Case %d:\n",cas++);
for(int i=;i<=q;++i){
scanf("%d",&v);
if(G.dis[v]==INF || G.dis[v]<|| G.incir[v] ) printf("?\n");
else printf("%d\n",G.dis[v]);
}
}
return ;
}

最新文章

  1. Unity Ragdoll(布娃娃系统)
  2. [Android] 关于getinstalledpackages参数的分析
  3. Vue#条件渲染
  4. LNK1169: one or more multiply defined symbols found
  5. 从快的线上callback hell代码说起
  6. 使用NDK c++建立一个Android应用
  7. php基础知识(1)
  8. 【nodejs】 npm 注意事项
  9. uva 10534
  10. mybatis第一个入门demo
  11. The 2014 ACM-ICPC Asia Mudanjiang Regional
  12. linux makefile 编译多个.c文件 实例
  13. 10.1 ES6 的新增特性以及简单语法
  14. linux命令应用之一
  15. GitHub下载子目录
  16. 20165317 学习基础和C语言基础调查
  17. tortoisegit 常见错误disconnected no supported authentication methods available(server sent: publickey)
  18. Structs复习 命名空间
  19. electron demo项目npm install安装失败解决办法
  20. ModelForm错误验证自定义钩子和全局钩子

热门文章

  1. 《Programming with Objective-C》第七章 Values and Collections
  2. VC++ 轻松实现“闪屏” SplashWnd
  3. WinError 5
  4. Docker(1)在CentOS上的安装与卸载
  5. 说说M451例程之PWM的寄存器讲解
  6. jquery将具有相同名称的元素的值提取出来放到一个数组内
  7. 【BZOJ3648】寝室管理 树分治
  8. 记一个在docker中运行多线程event_loop.run_forever()的bug
  9. DOS和BAT批量提取修改文件名
  10. .net core 启动域名及端口配置