题解 P3022 【[USACO11OPEN]奇数度Odd degrees】
3493441984zz · · 题解
动态规划?(我不会)
直接找规律搜索!!!
题外话:
可能本人的思路跟楼下们相同,反正我看不懂
所以我就自己琢磨,然后希望能表述清楚,我做完后偷瞄了楼下(尴尬)
思路:
这道题目不难,我也不知道怎么用
先说做法(至于为什么下文会提到):
我们搜索每一个没访问过的点,对于搜索进来的这条边,我们不管它,让它继续搜索下去,直到访问了每个节点后,统计度数,如果现在是偶数度的话,我们就连上最开始搜索进来的边,保证当前点是奇数度
知道你们现在还迷糊qwq ,来人啊,上性质!!!
于是我门开始找性质:
我们从
于是保留
那么又返回到
于是保留
所以我们就连了
等等??样例输出不是这样啊??
不是有苏卿念
那么样例输出是怎么来的呢??
其实是访问的顺序不一样导致的,那就再模拟一遍吧
我们还是从
那么保留的边就是
记得连边连双向边
最后到了美滋滋的代码时间~~~
#include<iostream>
#include<cstdio>
#include<algorithm>
#define N 50007
#define M 100007
using namespace std;
struct Edge
{
int to,nxt,id;
}edge[M<<1];
int n,m,cnt;
int head[N],ans[M];
bool vis[N];
void Add(int u,int v,int id)
{
edge[++cnt]=(Edge){v,head[u],id};
head[u]=cnt;
}
bool Dfs(int u)
{
vis[u]=1;
int du=0;
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(vis[v])
continue;
if(Dfs(v))
{
++du;
ans[++cnt]=edge[i].id;
}
}
if(du%2==0)
return 1;
else
return 0;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;++i)
{
int u,v;
scanf("%d%d",&u,&v);
Add(u,v,i);
Add(v,u,i);
}
cnt=0;
for(int i=1;i<=n;++i)
if(!vis[i])
if(Dfs(i))
{
printf("-1");
return 0;
}
sort(ans+1,ans+1+cnt);
printf("%d\n",cnt);
for(int i=1;i<=cnt;++i)
printf("%d\n",ans[i]);
}