NOIP 2017 Day 1題3:公園をぶらぶらする最短経路+ダイナミックプランニング


以下から抜粋:http://blog.csdn.net/enjoy_pascal/article/details/78592786   簡潔に書く
analysis
これはAK問題だと言われていますか?いいえ、そうではありません.
まず隣接テーブルで保存しながらspfaを1回走り、dis[i]は1からiの最短距離を表す(spfaができないとは言わないでください)  f[i][j]を1からiまでのすべてのパスのうちdis[n]より大きいKを表すパス数とする  だからある
f[i][j]=∑f[k][dis[i]−dis[k]+j−len[i][k]]
これを見て、あなたは
DP

メモリー検索!
 
我々は
n
スタート
逆検索
とします.
dis[i]−dis[k]+j−len[i][k]<0
もちろん検索はしません
では、私たちの最大の敵である判0環は?  f[x][y]という状態が1回のdfsに2回現れると、それは0リングがあり、returnがいいので、配列をつけてマークします.
finally
ans=(∑i=0nf[n][i])modp
彼のコード.書いています.....すでに7組のデータが通過し,0ループはまだ研究されている.
/*  
1
5 10 0 595078320
1 2 1
2 5 1
2 1 2
5 2 1
2 3 1
3 5 1
1 5 2
4 1 1
3 1 2
4 2 1
   2
    :4    */

#include 
using namespace std;
const  int MAX_N=100001;
struct edge{
    int to;
    int cost;
};
vector  G[MAX_N];
vector  ReG[MAX_N];

int dis[MAX_N];
int N,M,K,pmod;
int dp[MAX_N][51];
bool roll;

void input(){

    for(int i=0;i> N >> M >> K >> pmod;

    for(int i=1;i<=M;i++){

        int a,b,c; cin >> a >> b>>c;
        G[a].push_back(    (edge){b,c} );
        ReG[b].push_back(  (edge){a,c} );

    }

    memset(dp, 0 ,sizeof(dp));
    dp[1][0]=1;
    fill(dis ,dis+N+1, 200000000);
    roll=false;

}


int  dfs(int v,int k){
    if(dp[v][k]!=0) return dp[v][k];
    //used[v]=true;
    for(  int j=0; j P;
    priority_queue

,greater

> que; dis[1] = 0; que.push( P(0,1)); while( !que.empty()){ P p = que.top(); que.pop(); int v= p.second; if( dis[v] < p.first ) continue; for( int i=0 ; i dis[v] + e.cost ){ dis[e.to] = dis[v] + e.cost; que.push( P( dis[e.to] , e.to )); } } } } int main() { //freopen("park.in","r",stdin); //freopen("park.out","w",stdout); int T;cin>>T; while(T--){ input(); dijkstra(); int ans=0; for(int i=0;i<=K; i++){ ans = ( ans + dfs(N,i) ) % pmod; } //if(roll) cout << -1 <


NOIP 2017パーク巡り  ダイナミックプランニング!
http://blog.csdn.net/qq_38678604/article/details/78572603#t4  この1編はよく書けている
https://www.cnblogs.com/CQzhangyu/p/7825839.html
https://www.cnblogs.com/Dndlns/p/7895996.html 
//#define debug
#include 
using namespace std;
const  int MAX_N=1000001;
struct edge{
    int to;
    int cost;
};
vector  G[MAX_N];
//  vector  ReG[MAX_N];
long long  dis[MAX_N];   //      






int N,M,K,pmod;


// bool used[MAX_N];


//int rudu[MAX_N] ; //        
int dp[MAX_N][51];




vector O[MAX_N];  //      
vector RO[MAX_N];  //       






void input(){


    cin >> N >> M >> K >> pmod;


    for(int i=1;i<=M;i++){


        int a,b,c; cin >> a >> b>>c;
        G[a].push_back(  (edge){b,c} );
       // rudu[b]++;


        //ReG[b].push_back( (edge){a,c});
        if( c==0) {
                O[a].push_back(  (edge){b,c} ) ;
                RO[b].push_back(  (edge){a,c} ) ;
        }


    }


    memset(dp, 0 ,sizeof(dp));


    dp[1][0]=1;


    fill(dis ,dis+N+1, 2000);


//     for(int i=1;i<=M;i++){
//
//             for( int j=0;j vs  ; //        
bool atO[MAX_N];




void dfs(int v){
    used[v]=true;
    for(  int j=0; j=0 ;i--){
   //for(int i=0; i P;
    priority_queue

,greater

>  que;     dis[1] = 0;     que.push( P(0,1));     while( !que.empty()){         P p = que.top(); que.pop();         int v= p.second;         if( dis[v] < p.first ) continue;         for( int i=0 ; i dis[v] + e.cost ){                 dis[e.to] =  dis[v] + e.cost;                 que.push(  P( dis[e.to] , e.to ));             }         }     }  #ifdef debug       cout< qq;         qq.push(1);         us[1]=true;         while(!qq.empty()){             int s=qq.front();   qq.pop();             if( roll::atO[s] ) {    return -1;         }             for(  int j=0; j < G[s].size(); j++){                 edge e =  G[s][j];                 if(   e.cost + dis[s] - dis[e.to] > K ||  e.cost + dis[s] - dis[e.to]<0 ) continue;// !!                 else                 if( !us[e.to]) { qq.push(e.to) ; us[e.to] =true; };                 for(int k=0; k<=K; k++){                     int kk = k +  e.cost + dis[s] - dis[e.to] ;                     if(  (kk>=0) && (kk <= K) ){                             dp[e.to][ kk ]  = (  dp[e.to][ kk ]  +  dp[s ][ k ] );                             #ifdef debug                               cout << "from " <>t;     while(t--){         input();         dijkstra();         roll::scc();         if( BFS()==-1 ) cout << -1;         else{             int ans = 0;             for(int i=0;i<=K; i++){                        // cout <