http://acm.fzu.edu.cn/problem.php?pid=2321
竞赛图中如果存在环,那么肯定存在三元环,手画一下四元环,发现只有四元环没有三元环是不可能的
然后说明必须是DAG,那么DAG一定可以知道每个人的排名,那么我们dfs这个排名,然后去拓扑排序一下,每个点rudu没有归零说明这些边需要反过来,然后记录一下最小值就好
#include<cstdio>
#include<algorithm>
#include<vector>
#define pb push_back
using namespace std;
typedef long long ll;
const int maxl=20;
int n,m,cas,k,cnt,tot,ans;
int a[maxl],b[maxl],rudu[maxl];
vector<int> e[maxl];
char s[maxl];
bool in[maxl],vis[maxl];
inline void prework()
{
for(int i=1;i<=n;i++)
rudu[i]=0,e[i].clear(),in[i]=false;
for(int i=1;i<=n;i++)
{
scanf("%s",s+1);
for(int j=1;j<=n;j++)
if(s[j]=='1')
e[i].push_back(j),rudu[j]++;
}
}
inline void rec()
{
for(int i=1;i<=n;i++)
vis[i]=false,b[i]=rudu[i];
int ret=0,u,v,l;
for(int i=1;i<=n;i++)
{
u=a[i];ret+=b[u];vis[u]=true;
l=e[u].size();
for(int j=0;j<l;j++)
{
v=e[u][j];
if(!vis[v]) b[v]--;
}
}
ans=min(ans,ret);
}
inline void dfs(int k)
{
for(int i=1;i<=n;i++)
if(!in[i])
{
a[k]=i;in[i]=true;
if(k==n)
rec();
else
dfs(k+1);
a[k]=0;in[i]=false;
}
}
inline void mainwork()
{
ans=45;
dfs(1);
}
inline void print()
{
printf("%d\n",ans);
}
int main()
{
int t=1;
while(~scanf("%d",&n))
{
prework();
mainwork();
print();
}
return 0;
}