代码改变世界

Hackerrank Related questions

2014-12-18 15:45  达利园大面包  阅读(160)  评论(0)    收藏  举报

地址https://www.hackerrank.com/contests/quora-haqathon/challenges

这题有点坑,搞了我一个星期一度以为数据有问题,后来发现如果是星形图的话,我的程序瞬间退化到n^2级别了。

把每条边编号,正向反向都要,然后dp就行。

但是,仅仅这样会t的(星形图),为什么?自己想

我们可以记录每个点开始的答案res[u],如果已知res[u]要求dp[v->u],dp[v->u] = ((res[u]*drg[u]-a[u]) - dp[u->v])/(drg[u]-1) drg[u]==1记得特判

这样程序就能很快跑出来了

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <vector>
  4 #include <algorithm>
  5 using namespace std;
  6 #define N 200000
  7 #define INF 100000000
  8 int a[N+20];
  9 double dp[N*2+20],res[N+20];
 10 int dgr[N+20];
 11 //vector<int> road[N+20];
 12 struct Node{
 13     int v,next;
 14 }edge[N*2+20];
 15 int H[N+20],siz[N+20];
 16 int cnt = 0;
 17 pair<int,int> b[N*2+20];
 18 int m,tot;
 19 void addedge(int u,int v){
 20     tot++;
 21     edge[tot].v = v;
 22     edge[tot].next = H[u];
 23     H[u] = tot;
 24     siz[u]++;
 25 }
 26 void dfs(int x){
 27     int u = b[x].first;
 28     int v = b[x].second;
 29     dp[x] = a[v];
 30     /*for (int i=0;i<road[v].size();i++){
 31         int w = road[v][i];
 32         if (w==u) continue;
 33         int j = lower_bound(b,b+m,pair<int,int>(v,w)) - b;
 34         if (!vist[j]) dfs(j);
 35         dp[x] += dp[j]/(road[v].size()-1);
 36     }*/
 37     for (int i=H[v];i!=-1;i=edge[i].next){
 38         cnt++;
 39         int w = edge[i].v;
 40         if (w==u) continue;
 41         int j = lower_bound(b,b+m,pair<int,int>(v,w)) - b;
 42         if (!dp[j]) dfs(j);
 43         dp[x] += dp[j]/(siz[v]-1);
 44     }
 45 }
 46 void work(int u){
 47     /*for (int i=0;i<road[u].size();i++){
 48         int v = road[u][i];
 49         int j = lower_bound(b,b+m,pair<int,int>(u,v)) - b;
 50         res += dp[j]/(road[u].size());
 51     }*/
 52     for (int i=H[u];i!=-1;i=edge[i].next){
 53         int v = edge[i].v;
 54         int j = lower_bound(b,b+m,pair<int,int>(u,v)) - b;
 55         if (!dp[j]){
 56             int k = lower_bound(b,b+m,pair<int,int>(v,u)) - b;
 57             if (!res[v]) work(v);
 58             if (dgr[v]==1) dp[j] = a[v];
 59             else dp[j] =( (res[v]-a[v])*dgr[v] - dp[k])/(dgr[v]-1) + a[v];
 60         }
 61         res[u] += dp[j]/(siz[u]);
 62     }
 63     res[u]+=a[u];
 64 }
 65 int main(){
 66     freopen("input","r",stdin);
 67     int n;
 68     scanf("%d",&n);
 69     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
 70     tot = 0;
 71     memset(H,-1,sizeof(H));
 72     for (int i=0;i<n-1;i++){
 73         int u,v;
 74         scanf("%d%d",&u,&v);
 75         b[i<<1].first = u;
 76         b[i<<1].second = v;
 77         b[i<<1|1].first = v;
 78         b[i<<1|1].second = u;
 79         dgr[u]++;
 80         dgr[v]++;
 81         addedge(u,v);
 82         addedge(v,u);
 83     }
 84     m = 2*(n-1);
 85     sort(b,b+m);
 86     int u = 1;
 87     for (int i=H[u];i!=-1;i=edge[i].next){
 88         int v = edge[i].v;
 89         int j = lower_bound(b,b+m,pair<int,int>(u,v)) - b;
 90         if (!dp[j]) dfs(j);
 91         res[u] += dp[j]/(siz[u]);
 92     }
 93     res[u] += a[u];
 94     double mn = INF;
 95     int k;
 96     for (int i=1;i<=n;i++){
 97         if (!res[i]) work(i);
 98         if (res[i]<mn){
 99             mn = res[i];
100             k = i;
101         }
102     }
103     printf("%d\n",k);
104     return 0;
105 }