很好很难的一个题
思路参考点击打开链接
floyd+dfs二分图判定+二分图最大匹配
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
int book[510];
int maze[510][510];
int n,m,k,flag;
int inf=0x3f3f3f3f;
int g[510][510];
void floyd()
{
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(maze[i][j]>maze[i][k]+maze[k][j])
maze[i][j]=maze[i][k]+maze[k][j];
}
void graph()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(maze[i][j]<=k)
g[i][j]=1;
}
}
void dfs(int x,int c)
{
if(flag)
return;
int nc;
if(c==1)
nc=2;
else
nc=1;
for(int i=1;i<=n;i++)
{
if(i==x||g[x][i]==0)
continue;
if(book[i]==0)
{
book[i]=nc;
dfs(i,nc);
}
else if(book[i]==c)
{
flag=1;
return;
}
}
}
int linker[510];
int used[510];
int DFS(int u)
{
used[u]=1;
for(int v=1;v<=n;v++)
{
if(g[u][v]&&!used[v])
{
used[v]=1;
if(linker[v]==-1||DFS(linker[v]))
{
linker[v]=u;
linker[u]=v;
return 1;
}
}
}
return 0;
}
void solve()
{
flag=0;
memset(book,0,sizeof(book));
for(int i=1;i<=n;i++)
if(book[i]==0)
{
book[i]=1;
dfs(i,1);
}
//for(int i=1;i<=n;i++)
//printf("%d ",book[i]);
//puts("");
int res=0;
memset(linker,-1,sizeof(linker));
for(int u=1;u<=n;u++)
{
if(linker[u]==-1)
{
memset(used,0,sizeof(used));
if(DFS(u))
res++;
}
}
int cnt=0;
for(int i=1;i<=n;i++)
if(maze[1][i]<inf)
{
cnt++;
//cout<<maze[1][i]<<endl;
}
//cout<<flag<<cnt<<res<<endl;
if(res*2!=n||flag||cnt<n)
{
printf("Impossible\n");
return;
}
int ans[510];
int num=0;
for(int i=1;i<=n;i++)
{
if(book[i]==1)
ans[num++]=i;
}
printf("%d\n",num);
for(int i=0;i<num;i++)
printf("%d%c",ans[i],i==num-1?'\n':' ');
}
int main()
{
int t,u,v,w;
cin>>t;
while(t--)
{
cin>>n>>m>>k;
memset(maze,inf,sizeof(maze));
for(int i=1;i<=n;i++)
maze[i][i]=0;
memset(g,0,sizeof(g));
while(m--)
{
cin>>u>>v>>w;
maze[u][v]=min(maze[u][v],w);
maze[v][u]=min(maze[v][u],w);
}
floyd();
graph();
solve();
}
}