Extended Traffic LightOJ - 1074

2018-05-22  本文已影响0人  ChenKL

题意:
求最短路 权为差的立方及存在负权
思路:

  1. spfa_dfs 判负权 + spfa_bfs 求最短路 TLE
  2. spfa 直接判负环 无负环存在输出最小值
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cstdio>
using namespace std;
const int MAX_V = 210;
#define INF 1<<30
#define MAX_E 40000
struct edge{
  int v;
  int cost;
  int next;
};
struct edge es[MAX_E];
int head[MAX_V];
int len;
void add(int from,int to,int val)
{
    es[len].v=to;
    es[len].cost =val;
    es[len].next = head[from];
    head[from]=len++;
}
bool instack[MAX_V];
int d[MAX_V];
int V;
bool circle[MAX_V];
int inq_cnt[MAX_V];
void dfs(int s){
  circle[s] = true;
  for (int i = head[s];i != -1;i = es[i].next){
    if (!circle[es[i].v]) dfs(es[i].v);
  }
}
void spfa(int s){
  fill(d,d+V+1,INF);
  memset(instack,0,sizeof instack);
  memset(inq_cnt, 0, sizeof(inq_cnt));
  memset(circle,0,sizeof circle);
  d[s] = 0; instack[s] = true;
  inq_cnt[s]++;
  queue<int> Q;
  Q.push(s);
  while (!Q.empty()){
    int u = Q.front(); Q.pop();
    instack[u] = false;
    for (int i = head[u];i != -1;i = es[i].next){
      int v = es[i].v;
      if (circle[v]) continue;
      if (d[u] + es[i].cost < d[v]){
        d[v] = d[u] + es[i].cost;
        if (!instack[v]){
          Q.push(v);
          instack[v] = true;
          inq_cnt[v]++;
          if (inq_cnt[v] > V)
            dfs(v);
        }
      }
    }
  }
}
int cost[MAX_V];
void init(){
  memset(head,-1,sizeof head);
  scanf("%d",&V);
  for (int i = 1;i<=V;i++){
    scanf("%d",&cost[i]);
  }
  int E;
  scanf("%d",&E);
  len = 0;
  for (int i= 0;i<E;i++){
    int u,v,w;
    scanf("%d%d",&u,&v);
    w = (cost[v] -cost[u])*(cost[v] -cost[u])*(cost[v] -cost[u]);
    add(u,v,w);
  }
}
void solve(const int cnt){
  spfa(1);
  int q;
  scanf("%d",&q);
  printf("Case %d:\n",cnt);
  for (int i = 0;i<q;i++){
    int u;
    scanf("%d",&u);
    if (d[u] < 3 || circle[u] || d[u] == INF)
      printf("?\n");
    else
      printf("%d\n",d[u]);
  }
}
int main()
{
  int T;
  scanf("%d",&T);
  int cnt = 1;
  while (T-- > 0){
    init();
    solve(cnt++);
  }
  return 0;
}

``
上一篇下一篇

猜你喜欢

热点阅读