题目连接 http://codeforces.com/contest/954/problem/D #题目大意 n m s t 分别为点的个数, 边的个数,以及两个特殊的点 要求s与t间的距离在新增一条边下不变 #基本思路 用dj算法由s 到 t两个点分别进行一次计算 得出每一个点到s与t的最短值 遍历计算每两个没创建联系的边创建联系后,s与t的距离,并与初始时距离比较 若不变则记录(s与t的值一定为新建经由新建这条边的数值或原始值中最小一个)算法
#include <stdio.h> #include <algorithm> #include <queue> #include <bitset> #include <memory.h> #define MS 1010 #define END 0x3f3f3f3f using namespace std; int a[MS][MS]; //閭绘帴琛? priority_queue <int> q; void dijsktra(int start, int N, int d[MS]){ int i, j; bool v[MS]; memset(v, 0, sizeof(v)); d[start] = 0; for(i = 1; i < N; i++){ int x = 0; for(j = 1; j <= N; j++) if(!v[j] && (x == 0|| d[j] < d[x])) x = j; v[x] = 1; /* printf("%d\n", x);*/ for(j = 1; j <= N; j++){ d[j] = min(d[j], d[x]+a[x][j]); /* printf("%d %d\n", d[x], a[x][j]);*/ } } } int main(){ int N, M, S, T; int temp_x, temp_y; while(scanf("%d%d%d%d", &N, &M, &S, &T) == 4){ //init int i, j; memset(a, 0x3f, sizeof(a)); for(i = 0; i <= N; i++) a[i][i] = 0; for(i = 0; i < M; i++){ scanf("%d%d", &temp_x, &temp_y); a[temp_x][temp_y] = 1; a[temp_y][temp_x] = 1; } /* for(i = 1; i <= N; i++){ for(j = 1; j <= N; j++){ if(a[i][j] > 10) printf("* "); else printf("%d ", a[i][j]); } printf("\n"); }*/ int dt[MS], ds[MS]; memset(ds, 0x3f, sizeof(ds)); memset(dt, 0x3f, sizeof(dt)); dijsktra(T, N, dt); dijsktra(S, N, ds); int length = ds[T]; /* for(i = 0; i <= N; i++) printf("%d ", dt[i]); printf("\n"); printf("%d\n", length);*/ int count = 0; for(i = 1; i <= N; i++){ for(j = i+1; j <= N; j++){ if(a[i][j] == 1) continue; if(ds[i]+dt[j]+1 >= length && ds[j] + dt[i] +1 >= length){ /*printf("%d %d %d %d\n", i, j, ds[i]+dt[j]+1, ds[j]+dt[i]+1);*/ count++; } } } printf("%d\n", count); /* for(i = 1; i <= N; i++) printf("%d ", d[i]); printf("\n");*/ } }