洛谷 P2761 软件补丁问题 【spfa】

…为什么最短路的题会出现在网络流24里??
因为范围是15所以直接把每个状态作为一个点,向它能转移到的点连有向边即可。可以不用建图(据说建图存不下?),直接枚举m个转移方案。位运算比较麻烦注意不要写错。

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int N=1500005,inf=1e9;
int n,m,dis[N];
char c1[N],c2[N];
struct qwe
{
	int y,n,d,a,c;
}e[N];
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%s%s",&e[i].c,c1,c2);
		for(int j=0;j<n;j++)
		{
			if(c1[j]=='+')
				e[i].y^=(1<<(n-j-1));
			if(c1[j]=='-')
				e[i].n^=(1<<(n-j-1));
			if(c2[j]=='+')
				e[i].a^=(1<<(n-j-1));
			if(c2[j]=='-')
				e[i].d^=(1<<(n-j-1));
		}
	}
	int s=(1<<n)-1,t=0;
	queue<int>q;
	for(int i=t;i<=s;i++)
		dis[i]=inf;
	dis[s]=0;
	q.push(s);
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		for(int i=1;i<=m;i++)
			if((u&e[i].n)==0&&(u&e[i].y)==e[i].y)
			{
				int now=((u|e[i].d)^e[i].d)|e[i].a;
				if(dis[now]>dis[u]+e[i].c)
				{
					dis[now]=dis[u]+e[i].c;
					q.push(now);
				}
			}
	}
	printf("%d\n",dis[t]==inf?0:dis[t]);
	return 0;
}
posted @ 2018-02-06 11:28  lokiii  阅读(155)  评论(0编辑  收藏  举报