2017ACM-ICPC 青島 K.Our Journey of Xian Ends

題意很難讀。比賽時讀了半個小時,賽後又讀了一個小時,仍是有些模棱兩可。最後又問了問,大概知道是什麼意思了。c++

就是給定一些航班,每一個航班雙向鏈接一對城市。要求從西安出發,必須先到達上海而後到達青島,而後從青島回到上海浦東機場的最小費用spa

其中,每一個機場有登機區和降落區,每一個機場的登機區和降落區都只能通過一次。上海有浦東機場和虹橋機場兩個,兩個機場間能夠不坐飛機而且不消耗費用blog

對於點容量限制,能夠經過拆點來限制點容量,這是基本操做get

對於路徑限制,能夠經過源點匯點的設定來作到。若最大流爲滿則存在路徑string

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e4+8;
const int INF=0x7f7f7f7f;
struct fuck{
	int u,v,cap,w,next;
}edge[maxn<<4];
int head[maxn<<1];
int tol;
void init()
{
	tol=0;
	memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int w,int cap)
{
	edge[tol].u=u;
	edge[tol].v=v;
	edge[tol].cap=cap;
	edge[tol].w=w;
	edge[tol].next=head[u];
	head[u]=tol++;
	edge[tol].u=v;
	edge[tol].v=u;
	edge[tol].w=-w;
	edge[tol].cap=0;
	edge[tol].next=head[v];
	head[v]=tol++;
}
map<string,int> mp;
int idx;
int getid(char s[])
{
	if(mp.count(s)!=0)
		return mp[s];
	mp[s]=idx;addedge(idx*2-1,idx*2,0,1);idx++;
	return idx-1;
}
int dis[maxn<<1],pre[maxn<<1];
bool vis[maxn<<1];
bool spfa(int sour,int sink)
{
	queue<int>	q;
	q.push(sour);
	memset(dis,INF,sizeof(dis));
	memset(vis,false,sizeof(vis));
	dis[sour]=0;vis[sour]=true;pre[sour]=-1;
	int i,u,v;
	while(!q.empty())
	{
		u=q.front();q.pop();
		vis[u]=false;
		for(i=head[u];i!=-1;i=edge[i].next)
		{
			v=edge[i].v;
			if(edge[i].cap>0&&edge[i].w+dis[u]<dis[v])
			{
				dis[v]=dis[u]+edge[i].w;
				pre[v]=i;
				if(!vis[v])
					vis[v]=true,q.push(v);
			}
		}
	}
	if(dis[sink]>=INF)	return false;
	return true;
}
void Minicost(int sour,int sink)
{
	int co,fl;
	co=fl=0;
	while(spfa(sour,sink))
	{
		int mi=INF;
		for(int i=pre[sink];i!=-1;i=pre[edge[i^1].v]){
			if(mi>edge[i].cap)
				mi=edge[i].cap;
		}
		for(int i=pre[sink];i!=-1;i=pre[edge[i^1].v]){
			edge[i].cap-=mi;
			edge[i^1].cap+=mi;
		}
		fl+=mi;
		co+=dis[sink]*mi;
	}
	if(fl==3)
		printf("%d\n",co);
	else
		printf("-1\n");
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int m;
		scanf("%d",&m);
		init();idx=1;
		mp.clear();
		mp["Xian"]=idx;addedge(idx*2-1,idx*2,0,1);idx++;
		mp["Qingdao"]=idx;addedge(idx*2-1,idx*2,0,2);idx++;
		mp["Hongqiao"]=idx;addedge(idx*2-1,idx*2,0,2);idx++;
		mp["Pudong"]=idx;addedge(idx*2-1,idx*2,0,1);idx++;
		while(m--)
		{
			char s[12],c[12];
			int w;
			scanf("%s%s%d",s,c,&w);
			int u=getid(s);
			int v=getid(c);
			addedge(u*2,v*2-1,w,INF);
			addedge(v*2,u*2-1,w,INF);
		}
		int sour=0,sink=idx*2-1;
		addedge(sour,3*2-1,0,2);
		addedge(sour,4*2-1,0,1);
		addedge(1*2,sink,0,1);
		addedge(2*2,sink,0,2);
		Minicost(sour,sink);
	}
	return 0;
}
相關文章
相關標籤/搜索