/*给你有向图,有些边是可以直接走的,有些边是修之后才可以走,现在要想从1能到达所有的点,问你至少要修多少条路。解:现把 可以直接 走的边加进来,缩点,因为(1<n,m<1e6)。 然后从1点bfs,每个点初始都为0,可以直接的标记为-1,要修的边标记为边的编号,当再有不修路就能到达的话又把它标记为-1,。 所以,如果路全部修之后好不能到达,则有些点还为0。 点的标记>0,则说明修路之后才能到达。 要记录边的编号,应该用数组模拟邻接链表。*/#include<cstdio>#include<cstring>#include<iostream>#define N 100030using namespace std;int head[N];int n,m,x,y;int dfn[N],low[N],instack[N],num[N],edge[N],f[N],o[N],top,D,now,ans;bool inst[N];struct Node{ int u,v,f; int next;}ed[N];void tarjan(int i){ dfn[i]=low[i]=++D; inst[i]=1,instack[++top]=i; for (int p=head[i]; p; p=ed[p].next) { int j=ed[p].v; if(ed[p].f)continue; if (!dfn[j]) tarjan(j),low[i]=min(low[i],low[j]); else if (inst[j]) low[i]=min(low[i],dfn[j]); } if (low[i]==dfn[i]) { now++; int k; do k=instack[top--],inst[k]=0,num[k]=now; while (k!=i); }}void bfs(int x){ int h=0,t=1; f[1]=x; edge[x]=-1; while (h<t) { int i=f[++h]; for (int p=head[i]; p; p=ed[p].next) { //int j=vv[p]; int j=ed[p].v; if (!edge[j]) edge[j]=ed[p].f ?p:-1,f[++t]=j; else if (edge[j]>0 && !ed[p].f) edge[j]=-1; } }}void init(){ memset(head,0,sizeof(head)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(edge,0,sizeof(edge)); top=0; D=0; now=0;}void add(int u,int v,int f,int e){ ed[e].u=u; ed[e].v=v; ed[e].f=f; ed[e].next=head[u]; head[u]=e;}int main(){ freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); while(scanf("%d%d",&n,&m)!=EOF) { init(); int u,v,f; for (int i=1; i<=m; i++) { cin>>u>>v>>f; add(u,v,f,i); } for (int i=1; i<=n; i++) if (!dfn[i]) tarjan(i); memset(head,0,sizeof(head)); for (int i=1; i<=m; i++) { //int x=num[uu[i]],y=num[vv[i]]; //vv[i]=y; // if (x!=y) next[i]=head[x],head[x]=i; int x=num[ed[i].u]; int y=num[ed[i].v]; int f=ed[i].f; if(x!=y) { add(x,y,f,i); } } bfs(num[1]); ans=0; for (int i=1; i<=now; i++) if (edge[i]>0) o[++ans]=edge[i]; for (int i=1; i<=now; i++) if (!edge[i]) ans=-1; printf("%d\n",ans); for (int i=1; i<=ans; i++) printf("%d%s",o[i],i<ans?" ":"\n"); } return 0;}