ZOJ2923 Calculate Roads(SPFA의 dp)

2910 단어 SPFA

그림 dp를 배운 후 처음으로 응용한 셈이다.제목은 사실 매우 엄격하지 않다. 아무 말도 하지 않았다. 기본적으로 추측에 의존한다. 게다가 엄밀히 말하면 데이터에 인트가 폭발할 것이다. 그러나 그렇게 많든 사고방식이 맞으면 된다. - 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;

}


좋은 웹페이지 즐겨찾기