[NOI2005] with cocoa Congcong

Input formats:

Behavioral data of the first two integers  N and  E, separated by spaces, respectively, the number of paths of interest in a number of attractions and connecting adjacent forests.

Line 2 contains two integers  C and  M, separated by spaces, respectively, and the initial cocoa Congcong where the number of attractions.

Next E lines of two integers, the second  I 2 + I + two integer of 2 rows  A I and  B I represents attractions  A I and attractions  B I  there is a path between. All are undirected way, that is: if A walk from the B, B can come from A.

Ensure that no more than one input directly connected path between any two points of interest, and must be directly or indirectly connected between the path Congcong and cocoa.

Output formats:

Output a real number, rounded to three decimal places, represents the average number of time units Cong Cong cocoa will eat.

For 50% of the data, . 1 N . 5 0.
For all data, . 1 N , E . 1 0 0 0.

answer

 When the Cong Cong and cocoa certain position, then the Cong Cong and the walk is certain;

Per unit time, Cong Cong take up to two steps, cocoa go one step further, so it must be getting closer, then dfs dp are sure to get the answer.

Prior to processing the i position when Congcong cocoa at position j, Cong Cong next move Go [i] [j]

Implement Dijkstra method is to use the shortest distance between each of the obtained two points, and then enumerate point, if dis [i] [j] == dis [y] [j] +1, then y this path may be the next point on the i, go to min

Since n is small, it will not T

When divided by dfs (du [kk] +1), can not move as cocoa

#include <bits / STDC ++ H.>
 the using  namespace STD; 

const  int MAXN = 1005 ;
 int n-, m;
 int S, T; // Cong Cong, cocoa 
int du [MAXN];
 int Go [MAXN] [MAXN]; // shortest i to j, i of the next 
Double F [MAXN] [MAXN];
 int CNT, head [MAXN];
 struct Edge {
     int Y, Next; 
} E [MAXN << . 1 ]; 

int min ( int X, int Y) { return X <Y? X: Y;} 

void the Add ( int x,int y){
    e[++cnt]=(edge){y,head[x]};
    head[x]=cnt;
}

int dis[maxn][maxn];
bool vis[maxn];

void ds(int s){
    memset(vis,false,sizeof(vis));
    priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;
    q.push(make_pair(0,s));
    dis[s][s]=0;
    while(!q.empty()){
        int x=q.top().second;
        q.pop();
        if(vis[x]) continue;
        vis[x]=true;
        for(int i=head[x];i;i=e[i].next){
            int y=e[i].y;
            if(dis[s][y]>dis[s][x]+1){
                dis[s][y]=dis[s][x]+1;
                q.push(make_pair(dis[s][y],y));
            }
        }
    }
}

double dfs(int cc,int kk){
    if(cc==kk) return 0.0;
    if(go[cc][kk]==kk) return 1.0;
    if(go[go[cc][kk]][kk]==kk) return 1.0;
    if(f[cc][kk]!=-1.0) return f[cc][kk];
    double ret=0;
    for(int i=head[kk];i;i=e[i].next){
        int y=e[i].y;
        ret+=(dfs(go[go[cc][kk]][kk],y)+1.0)/(du[kk]+1);
    }
    ret+=(dfs(go[go[cc][kk]][kk],kk)+1.0)/(du[kk]+1);
    return f[cc][kk]=ret;
}

int main(){
    memset(dis,0x3f,sizeof(dis));
    scanf("%d%d",&n,&m);
    scanf("%d%d",&S,&T);
    memset(go,0x3f,sizeof(go));
    for(int i=1;i<=m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        du[x]++;du[y]++;
        add(x,y);add(y,x);
    }
    for(int i=1;i<=n;i++)
     ds(i);
//    for(int i=1;i<=n;i++,putchar(10))
//     for(int j=1;j<=n;j++)
//      printf("%d ",dis[i][j]);
    for(int i=1;i<=n;i++)
     for(int k=head[i];k;k=e[k].next){
         int y=e[k].y;
         for(int j=1;j<=n;j++)
          if(dis[i][j]==dis[y][j]+1)
           go[i][j]=min(go[i][j],y);
     }
    for(int i=1;i<=n;i++)
     for(int j=1;j<=n;j++)
      f[i][j]=-1.0;
    printf("%.3lf",dfs(S,T));
}
View Code

 

Guess you like

Origin www.cnblogs.com/sto324/p/11209369.html