二分答案
对于一个点,最多能删一条相连的边,每一种颜色最多能有一条相连的边,那么把每个点相连的边用前缀优化建图就可以了
#include
#include
#include
#include
#include
using namespace std;
const int N=1000010;
int n,m,cnt,tot,G[N];
struct iedge{
int s,t,w,c,g;
}ie[N];
int tmp[N],icnt;
vector e[N];
struct edge{
int t,nx;
}E[N<<1];
inline void addedge(int x,int y,int c,int t,int g){
e[x].push_back({x,y,t,c,g}); e[y].push_back({x,y,t,c,g});
}
vector<int> cc[N];
int tt[N],iit;
inline void addedge(int x,int y){
//cout<
E[++cnt].t=y; E[cnt].nx=G[x]; G[x]=cnt;
}
int vis[N],g[N],dfn[N],low[N],s[N],tp,iiit,ig;
void tarjan(int x){
dfn[x]=low[x]=++iiit; vis[x]=1; s[++tp]=x;
for(int i=G[x];i;i=E[i].nx){
if(!vis[E[i].t]) tarjan(E[i].t);
if(vis[E[i].t]!=2) low[x]=min(low[x],low[E[i].t]);
}
if(dfn[x]==low[x]){
int k; ++ig;
do{ k=s[tp--]; vis[k]=2; g[k]=ig; }while(tp && k!=x);
}
}
int lst[N];
inline bool check(int x){
memset(G,0,sizeof(G)); cnt=0;
memset(vis,0,sizeof(vis));
for(int i=1;i<=m;i++)
if(ie[i].w>x) addedge(i<<1|1,i<<1);
tot=(m<<1|1)+1;
for(int i=1;i<=n;i++){
++iit;
vector<int> a,b;
for(auto u : e[i]){
if(tt[u.c]!=iit) tt[u.c]=iit,cc[u.c].clear(),a.push_back(u.c);
cc[u.c].push_back(u.g); b.push_back(u.g);
}
if(!b.size()) continue;
addedge(b[0]<<1|1,tot); addedge(tot+1,b[0]<<1);
for(int j=1;j1 <<1),tot+(j<<1));
addedge(tot+(j<<1|1),tot+(j-1<<1|1));
addedge(b[j]<<1|1,tot+(j<<1));
addedge(tot+(j<<1|1),b[j]<<1);
addedge(b[j]<<1|1,tot+(j-1<<1|1));
addedge(tot+(j-1<<1),b[j]<<1);
}
tot+=(b.size()<<1|1)+1;
for(int u : a){
if(cc[u].size()<2) continue;
addedge(cc[u][0]<<1,tot);
addedge(tot+1,cc[u][0]<<1|1);
for(int j=1;j1<<1),tot+(j<<1));
addedge(tot+(j<<1|1),tot+(j-1<<1|1));
addedge(cc[u][j]<<1,tot+(j<<1));
addedge(tot+(j<<1|1),cc[u][j]<<1|1);
addedge(cc[u][j]<<1,tot+(j-1<<1|1));
addedge(tot+(j-1<<1),cc[u][j]<<1|1);
}
tot+=(cc[u].size()<<1|1)+1;
}
}
tp=iiit=ig=0;
for(int i=2;i<=tot;i++)
if(!vis[i]) tarjan(i);
for(int i=1;i<=m;i++)
if(g[i<<1]==g[i<<1|1]) return false;
memcpy(lst,g,sizeof(g));
return true;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1,x,y,c,t;i<=m;i++)
scanf("%d%d%d%d",&x,&y,&c,&t),ie[i]={x,y,t,c,i},tmp[++icnt]=c;
sort(tmp+1,tmp+1+icnt); icnt=unique(tmp+1,tmp+1+icnt)-tmp-1;
for(int i=1;i<=m;i++) ie[i].c=lower_bound(tmp+1,tmp+1+icnt,ie[i].c)-tmp;
for(int i=1;i<=m;i++) addedge(ie[i].s,ie[i].t,ie[i].c,ie[i].t,i);
int l=0,r=1e9,mid,ans=-1;
//int ss=check(3);
while(l<=r)
check(mid=l+r>>1)?r=(ans=mid)-1:l=mid+1;
vector<int> pt;
if(!~ans) return puts("No"),0;
puts("Yes");
for(int i=1;i<=m;i++)
if(lst[i<<1|1]1]) pt.push_back(i);
printf("%d %d\n",ans,pt.size());
for(int u : pt) printf("%d ",u);
return 0;
}