1. 程式人生 > 實用技巧 >2019南昌ICPC A Funny Bipartite Graph (爆搜)

2019南昌ICPC A Funny Bipartite Graph (爆搜)

本題資料範圍很小,因此直接根據右側爆搜左側選擇哪個,再加上一個可行性剪枝就行

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int inf=0x3f3f3f3f;
const int N=1e5+10;
const int mod=1e9+7;
char g[20][20];
char a[20][20];
int in[N],tag[N],w[N];
vector<int> go[N];
vector<int
> con[N]; int n; ll ans=1e18; void init(){ int i; memset(in,0,sizeof in); memset(tag,0,sizeof tag); for(i=0;i<=n;i++){ go[i].clear(); con[i].clear(); } } int cal(int x,int y) { if(!y) return 0; int ans=1; for(int i=1;i<=y;++i) ans=(ans*x);
return ans; } void dfs(int u,ll sum){ if(u==n+1){ ans=min(ans,sum); return ; } if(sum>=ans){ return ; } for(auto x:go[u]){ if(!tag[x]){ for(auto y:con[x]){ tag[y]++; } in[x]++; dfs(u
+1,sum+cal(w[x],in[x])-cal(w[x],in[x]-1)); in[x]--; for(auto y:con[x]){ tag[y]--; } } } } int main(){ ios::sync_with_stdio(false); int t; cin>>t; while(t--){ cin>>n; init(); ans=1e18; int i,j; for(i=1;i<=n;i++){ for(j=1;j<=n;j++){ cin>>g[i][j]; if(g[i][j]=='1'){ go[j].push_back(i); } } } for(i=1;i<=n;i++){ for(j=1;j<=n;j++){ cin>>a[i][j]; if(a[i][j]-'0'){ con[i].push_back(j); con[j].push_back(i); } } } for(i=1;i<=n;i++) cin>>w[i]; int sign=0; for(i=1;i<=n;i++){ if((int)go[i].size()==0){ sign=1; break; } } if(sign){ cout<<-1<<endl; } else{ dfs(1,0); if(ans==1e18){ cout<<-1<<endl; } else cout<<ans<<endl; } } return 0; }
View Code