第一次做二分图染色qwq,用了一个下午qwq,看电脑看的我眼睛难受
这个题满足二分的性质,因此二分图+二分……
#include#include #include #include #include #include using namespace std;struct in{ int to,ne,co;}ter[200020]; queue qwq;bool flag;int n,m,t,x,l,r,y,z,tail,head[200020],col[20005],a[100005];inline void build(int f,int l,int c){ ter[++tail]=(in){l,head[f],c},head[f]=tail; ter[++tail]=(in){f,head[l],c},head[l]=tail;}inline void bfs(int xx,int qi){ if(!flag)//如果之前发现当前答案不能满足则直接返回 return; while(!qwq.empty()) qwq.pop(); qwq.push(qi); col[qi]=1; while(!qwq.empty()) { int qaq=qwq.front(); for(int i=head[qaq];i;i=ter[i].ne) { if(ter[i].co<=xx)//如果说这对犯人的怒气值小于当前答案,则说明他们可以被接受 continue; if(col[ter[i].to]>0)//如果现在找到的点之前被走过 { if(col[ter[i].to]==col[qaq])//且颜色与现在的队首颜色相同 { flag=0;return;//当前答案不成立,返回 } } else//否则染色 col[ter[i].to]=3-col[qaq],qwq.push(ter[i].to); } qwq.pop(); }}inline bool ask(int xia){ int biao=a[xia]; memset(col,-1,sizeof(col)); flag=1; for(int i=1;i<=n;i++) if(col[i]<0)//如果这个点没有走过 bfs(biao,i); return flag;}int main(){ scanf("%d%d",&n,&m); memset(head,-1,sizeof(head)); for(int i=1;i<=m;i++) scanf("%d%d%d",&x,&y,&z),build(x,y,z),a[i+1]=z; a[1]=0; sort(a+1,a+2+m);//先排个序,便于下面二分 l=1,r=m+1;//l,r是数组下标 while(l >1; if(ask(mid))//如果返回值为真,则说明现在的答案太大,可以进一步缩小 r=mid; else//否则说明答案太小 l=mid+1; } printf("%d",a[l]);}