傳送門
解析:
這道題與網絡流什麼關係都沒有。都沒有。。都沒有。。。
那它爲什麼在網絡流24題裏面啊?!!!!
思路:
我真的是一臉懵逼,我連最短路做法都想出來了還是沒有想出來網絡流怎麼做,然而網上也並沒有找到網絡流做法,如果正在讀這篇博客的您有思路或者看到過這道題的網絡流做法,歡迎告知博主。
那麼就直接最短路一陣亂搞過去吧。
注意不要試圖建邊,一不小心就很可能,畢竟這是一個有點大而且複雜的圖。
直接在跑最短路的時候枚舉每一個補丁跑最短路就行了。
代碼:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
cs int N=(1<<20)+9;
int b1[101],b2[101];
int f1[101],f2[101];
int w[101];
int dist[N];
bool vis[N];
set<pair<int,int> > q;
int n,m;
inline void dijkstra(){
memset(dist,0x3f,sizeof dist);
dist[(1<<n)-1]=0;
q.insert(make_pair(0,(1<<n)-1));
while(!q.empty()){
int u=q.begin()->second;
q.erase(q.begin());
if(vis[u])continue;
vis[u]=true;
for(int re i=1;i<=m;++i){
if((u&b1[i])==b1[i]&&(u&b2[i])==0){
int to=f1[i]&u;
to=u^to;
to|=f2[i];
if(dist[to]>dist[u]+w[i]){
q.erase(make_pair(dist[to],to));
dist[to]=dist[u]+w[i];
q.insert(make_pair(dist[to],to));
}
}
}
}
}
char s[100];
signed main(){
scanf("%d%d",&n,&m);
for(int re i=1;i<=m;++i){
scanf("%d",&w[i]);
scanf("%s",s);
for(int re j=0;j<n;++j){
switch(s[j]){
case '-':{
b2[i]|=1<<j;
break;
}
case '+':{
b1[i]|=1<<j;
break;
}
}
}
scanf("%s",s);
for(int re j=0;j<n;++j){
switch(s[j]){
case '-':{
f1[i]|=1<<j;
break;
}
case '+':{
f2[i]|=1<<j;
break;
}
}
}
}
dijkstra();
printf("%d",dist[0]==0x3f3f3f3f?0:dist[0]);
return 0;
}