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;

}

 

你可能感兴趣的:(SPFA)