经典最短路题目。
这题空间不够时间足够,可以不建边,直接跑dij即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define re register
#define ls (o<<1)
#define rs (o<<1|1)
//#define m (l+r)/2
#define pb push_back
typedef pair<int,int> pii;
const double PI= acos(-1.0);
const int N = (1<<20)+777;
const int M = N*100;
/*
int head[M],cnt=1;
void init(int n){cnt=1;for(int i=0;i<=n;i++)head[i]=0;}
struct EDGE{int to,nxt,w;}ee[M];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
char s[111][22],p[111][22];
int a[22];int n,m,w;
int vs[N],d[N],cost[110];
typedef pair<int,int> pii;
void dij(int S,int T){
priority_queue<pii,vector<pii>,greater<pii> >q;
memset(d,0x3f,sizeof(d));
d[S]=0;
q.push({d[S],S});
while(!q.empty()){
pii tp=q.top();q.pop();
int x=tp.second;
if(vs[x])continue;vs[x]=1;
for(int i=1;i<=n;i++)if(x>>(i-1)&1)a[i]=1;else a[i]=0;
for(int i=1;i<=m;i++){
//bool f=true;
int tp=x,w=cost[i];
for(int j=1;j<=n;j++){
if(s[i][j]=='-'&&a[j])break;
if(s[i][j]=='+'&&!a[j])break;
if(p[i][j]=='+')tp|=(1<<(j-1));
if(p[i][j]=='-')if(tp>>(j-1)&1)tp-=1<<(j-1);
if(j==n){
if(x==tp)continue;
// cout<<x<<" -> "<<tp<<" "<<w<<endl;
if(d[tp]>d[x]+w){
d[tp]=d[x]+w;
q.push({d[tp],tp});
}
}
}
}
}
if(d[T]==0x3f3f3f3f)cout<<0<<endl;
else cout<<d[T]<<endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>cost[i]>>(s[i]+1)>>(p[i]+1);
}
dij((1<<n)-1,0);
return 0;
}