ZOJ2923 Calculate Roads(SPFA上的dp)
算是学了图dp后的第一次应用吧。题目其实真的是非常不严谨,什么都没说,基本靠猜,而且严格来说数据应该会有爆int的,不过不管那么多啦,思路对了就好- -0
#include<iostream> #include<cstring> #include<string> #include<cstdio> #include<vector> #include<cmath> #include<queue> #define ll long long #define maxn 5000 #define maxm 1000000 #define inf 0x3f3f3f3f using namespace std; vector<int> G[maxn+50]; struct Node { int v,k; Node(){} Node(int vi,int ki):v(vi),k(ki){} }; int m,n,k; int dis[maxn+50][55]; int num[maxn+50][55]; int vis[maxn+50][55]; int vtype[maxn]; int main() { while(cin>>m>>n>>k) { for(int i=0;i<=n;i++) G[i].clear(); int xi,yi; for(int i=0;i<n;i++) { scanf("%d%d",&xi,&yi); vtype[xi]=yi; } for(int i=0;i<m;i++){ scanf("%d%d",&xi,&yi); G[xi].push_back(yi); G[yi].push_back(xi); } memset(dis,0x3f,sizeof(dis)); memset(num,0,sizeof(num)); queue<Node> que; if(vtype[1]==0){ dis[1][0]=0; num[1][0]=1; que.push(Node(1,0)); } else{ dis[1][1]=0; num[1][1]=1; que.push(Node(1,1)); } while(!que.empty()){ Node xx=que.front();que.pop(); vis[xx.v][xx.k]=0; int u=xx.v; int kk=xx.k; for(int i=0;i<G[u].size();i++){ int v=G[u][i]; if(vtype[v]==0){ if(vis[v][kk]){ if(dis[u][kk]+1<dis[v][kk]){ dis[v][kk]=dis[u][kk]+1; num[v][kk]=num[u][kk]; } else if(dis[u][kk]+1==dis[v][kk]){ num[v][kk]+=num[u][kk]; } } else{ if(dis[u][kk]+1<dis[v][kk]){ dis[v][kk]=dis[u][kk]+1; num[v][kk]=num[u][kk]; que.push(Node(v,kk)); vis[v][kk]=1; } else if(dis[u][kk]+1==dis[v][kk]){ num[v][kk]+=num[u][kk]; que.push(Node(v,kk)); vis[v][kk]=1; } } } else{ if(kk==k) continue; if(vis[v][kk+1]){ if(dis[u][kk]+1<dis[v][kk+1]){ dis[v][kk+1]=dis[u][kk]+1; num[v][kk+1]=num[u][kk]; } else if(dis[u][kk]+1==dis[v][kk+1]){ num[v][kk+1]+=num[u][kk]; } } else{ if(dis[u][kk]+1<dis[v][kk+1]){ dis[v][kk+1]=dis[u][kk]+1; num[v][kk+1]=num[u][kk]; que.push(Node(v,kk+1)); vis[v][kk+1]=1; } else if(dis[u][kk]+1==dis[v][kk+1]){ num[v][kk+1]+=num[u][kk]; que.push(Node(v,kk+1)); vis[v][kk+1]=1; } } } } } int mdis=inf; for(int i=0;i<=k;i++){ mdis=min(mdis,dis[n][i]); } if(mdis==inf) { puts("Impossible!");continue; } int ans=0; for(int i=0;i<=k;i++){ if(dis[n][i]==mdis) ans+=num[n][i]; } cout<<ans<<endl; } return 0; }