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;
}
原文地址:https://www.cnblogs.com/chanme/p/3628995.html