【bzoj4061】[Cerc2012]Farm and factory

来源:互联网 发布:推荐手机支架 知乎 编辑:程序博客网 时间:2024/06/03 16:49

  这题不错
  反正我想了一天是没想出来hhhh
  后来看了糖老师的题解 恍然大悟
  设dis[i][j],dis[i][j]分别为原图和新图中i到j的最短路径。
  设新加的一个点为x
  若要使在新图中最短路不经过x,应要满足
  u,dis[u][x]>=max{dis[u][1]dis[x][1],dis[u][2]dis[x][2]}
  这个还是能想得到的
  得到了这个以后,因为要使dis[u][x]最小,故应该取等号。把这个式子写出来,就会是
  max{dis[u][1]dis[x][1],dis[u][2]dis[x][2]}
  如果把每个(dis[u][1],dis[u][2])看做一个点,答案就是是这些点到点(dis[x][1],dis[x][2])的切比雪夫距离和的最小值。
  于是就乱搞咯2333
  用dijkstra,时间复杂度O(m+nlogn)。亲测SPFA会TLE,不知道是不是姿势问题。

#include <bits/stdc++.h>using namespace std;#define rep(i,a,b) for(int i=a;i<=b;i++)#define per(i,a,b) for(int i=a;i>=b;i--)#define fore(i,u)  for(int i=head[u];i;i=nxt[i])#define cr(x) memset(x , 0 , sizeof x)#define pii pair<ll , int>#define mp make_pair#define maxn 100003#define maxm 600007inline int rd() {    char c = getchar();    while (!isdigit(c)) c = getchar() ; int x = c - '0';    while (isdigit(c = getchar())) x = x * 10 + c - '0';    return x;}typedef long long ll;typedef int arr_int[maxn];typedef ll  arr_ll [maxn];typedef int adj[maxm];const ll inf = 1e12;arr_int head , vis;arr_ll  dis[2] , x , y;adj to , val , nxt;int n , m , ett;priority_queue<pii , vector<pii> , greater<pii> > Q;inline void ins(int u , int v , int w) {    to[++ ett] = v , val[ett] = w , nxt[ett] = head[u] , head[u] = ett;}void input() {    n = rd() , m = rd();    cr(head) , ett = 0;    rep (i , 1 , m) {        int u = rd() , v = rd() , w = rd();        ins(u , v , w) , ins(v , u , w);    }}void dijk(int s) {    int c = s - 1;    rep (i , 1 , n) dis[c][i] = inf;    cr(vis);    dis[c][s] = 0;    Q.push(mp(0 , s));    while (!Q.empty()) {        int u = Q.top().second ; Q.pop();        if (vis[u]) continue;        vis[u] = 1;        fore (i , u) {            int v = to[i] , w = val[i];            if (dis[c][v] > dis[c][u] + w) {                dis[c][v] = dis[c][u] + w;                Q.push(mp(dis[c][v] , v));            }        }    }}void solve() {    dijk(1) , dijk(2);    rep (i , 1 , n) {        x[i] = dis[0][i] + dis[1][i];        y[i] = dis[0][i] - dis[1][i];    }    sort(x + 1 , x + n + 1) , sort(y + 1 , y + n + 1);    ll nx = x[(n + 1) / 2] , ny = y[(n + 1) / 2];    double ans = 0;    rep (i , 1 , n)        ans += abs(x[i] - nx) + abs(y[i] - ny);    printf("%.12lf\n" , ans / (2.0 * n));}int main() {    #ifndef ONLINE_JUDGE        freopen("data.txt" , "r" , stdin);    #endif    int T = rd();    rep (i , 1 , T) {        input();        solve();    }    return 0;}
0 0
原创粉丝点击