CF576D Flights for Regular Customers

The meaning of problems

Given a directed graph, edges for \ (I \) have limit \ (D_i \) , while walking indicates \ (I \) must travel at least the front \ (D_i \) strips of the other sides. From \ (1 \) to (n-\) \ happened to go several edges.
No solution output \ (Impossible \)

Thinking

A special bar
first by \ (D \) sorted in ascending order of magnitude
and then into \ (m \) time processing, \ (CAN [I] [J] \) represents the current time \ (I \) can come \ (j \)

Update \ (can \) that is the last time multiplied by the adjacency matrix \ (d_i-d_ {last} \) power (note the changing adjacency matrix, each finished with a plus side)
update the answer when, we enumerate each point.
If \ (1 \) can come \ (i \) point, then update the answer is \ (d_i (current time went i) + dis [i] [ n] ( i have to walk from the road) \) .
The shortest route \ (floyd \) to solve can. Considering the large d, rapid acceleration power matrix.
When the matrix multiplication with \ (bitset \) optimization.


#include <bits/stdc++.h>
using namespace std;
const int N=160;
int ans=0x3f3f3f3f,n,m,dis[N][N],last;
bitset<N> can[N],a[N],t[N];
struct edge{
    int x,y,d;
}e[N];
bool cmp(edge x,edge y){
    return x.d<y.d;
}
void mul(bitset<N> *a,bitset<N> *b){
    bitset<N> tt[N];
    for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
            if (a[i][j]) tt[i]|=b[j];
    for (int i=1;i<=n;i++) a[i]=tt[i];
}
void ksm(bitset<N> *a,int y){
    bitset <N> Ans[N];
    for (int i=1;i<=n;i++) Ans[i][i]=1;
    for (;y;y>>=1,mul(a,a))
        if (y&1) mul(Ans,a);
    for (int i=1;i<=n;i++) a[i]=Ans[i];
}
int main(){
    scanf("%d%d",&n,&m);
    for (int i=1;i<=m;i++)
        scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].d);
    sort(e+1,e+m+1,cmp);
    memset(dis,0x3f,sizeof(dis));
    for (int i=1;i<=n;i++) dis[i][i]=0,can[i][i]=1;
    for (int i=1;i<=m;i++){
        int x=e[i].x,y=e[i].y,d=e[i].d;
        for (int j=1;j<=n;j++) t[j]=a[j];
        ksm(t,d-last);
        mul(can,t);
        for (int j=1;j<=n;j++)
            for (int k=1;k<=n;k++)
                dis[j][k]=min(dis[j][k],dis[j][x]+1+dis[y][k]);
        for (int j=1;j<n;j++) if (can[1][j]) {
            ans=min(ans,d+dis[j][n]);
        }
        last=d;
        a[x][y]=1;
    }
    if (ans<0x3f3f3f3f) printf("%d\n",ans);
    else puts("Impossible");
    return 0;
}

postscript

Is kept hanging, such as what \ (i, j \) or \ (n, N \) Write trans
There \ (ANS \) initialization is not too large nor too small

Guess you like

Origin www.cnblogs.com/flyfeather6/p/11718468.html