看题的时候,看不出这是最小顶点覆盖,悲剧。
注意点:1,顶点从0开始,所以,my[]的标记不能以0为标准。
2,枚举法确实很不错。
#include<iostream>
#include<string>
using namespace std;
int n,m;
int f[220];
class node
{
public:
int to;
int next;
};
int head[220],vis[220],my[220],del[220];
node e[20002];
int cnt;
void add(int a,int b)
{
e[++cnt].to =b;
e[cnt].next= head[a];
head[a]=cnt;
}
bool dfs(int k)
{
for(int u=head[k];u!=-1;u=e[u].next)
{
int v=e[u].to;
if(!vis[v]&&!del[v])
{
vis[v]=1;
if(my[v]==-1||dfs(my[v]))
{
my[v]=k;
return true;
}
}
}
return false;
}
int get()
{
int now =0,i;
memset(my,-1,sizeof(my));
for(i=0;i<n;i++)
{
if(f[i]==0) continue;
if(del[i]) continue;
memset(vis,0,sizeof(vis));
if(dfs(i))
now++;
}
return now;
}
void solve()
{
memset(del,0,sizeof(del));
int sum =get(),now=sum,i;
int ans[220],len=0;
for(i=0;i<n;i++)
{
del[i]=1;
bool flag=true;
int k=get();
if(k+1==now)
{
now--;
ans[len++]=i;
flag=false;
}
if(flag) del[i]=0;
}
cout<<sum<<" ";
for(i=0;i<len;i++)
cout<<ans[i]<<" ";
cout<<endl;
}
void in()
{
cin>>n>>m;
for(int i=0;i<n;i++)
{
cin>>f[i];
head[i]=-1;
}
for(int i=0;i<m;i++)
{
int a,b;
cin>>a>>b;
if(a==b) continue;
if(f[a]==f[b]) continue;
add(a,b);
add(b,a);
}
}
int main()
{
int test;
cin>>test;
while(test--)
{
cnt=0;
in();
solve();
}
return 0;
}