zoukankan      html  css  js  c++  java
  • [洛谷P1262][题解]间谍网络

    题目在这里!

    题意

    给你一个图,有些点上有权值,只能从有权值的点出发,问遍历这个图经过的结点权值和最小是多少

    题解

    我们先想一想,什么情况是不可能遍历完的呢?
    要考虑这个问题,最好的方法就是看一看一些特殊的点。
    我们发现:若一个入度为0的点没有权值,则她一定不会被遍历到(显而易见)
    所以我们只需判断这些入度为0的点就可以啦~
    那么如何求最小权值和呢?
    当然要请我们的塔老爷子来帮忙啦~
    Tarjan缩点,然后求一下每个强连通分量里权值最小的那一个,加起来
    没了
    Code:

    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<ctime>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<stack>
    #include<queue>
    #include<vector>
    #include<bitset>
    #include<set>
    #include<map>
    #define LL long long
    #define rg register
    #define us unsigned
    #define eps 1e-6
    #define INF 0x3f3f3f3f
    #define ls k<<1
    #define rs k<<1|1
    #define tmid ((tr[k].l+tr[k].r)>>1)
    #define nmid ((l+r)>>1)
    #define Thispoint tr[k].l==tr[k].r
    #define pushup tr[k].wei=tr[ls].wei+tr[rs].wei
    #define pub push_back
    #define lth length
    using namespace std;
    inline void Read(int &x){
    	int f=1;
    	char c=getchar();
    	x=0;
    	while(c<'0'||c>'9'){
    		if(c=='-')f=-1;
    		c=getchar();
    	}
    	while(c>='0'&&c<='9'){
    		x=(x<<3)+(x<<1)+c-'0';
    		c=getchar();
    	}
    	x*=f;
    }
    #define N 3010
    int n,p,r,ans,bel[N],vis[N],low[N],dfn[N],pri[N],tim,tot;
    struct Edge {
    	int to,nxt;
    }e[N<<1];
    int head[N],cnt;
    inline void ade(int u,int v){
    	e[++cnt].to=v;
    	e[cnt].nxt=head[u];
    	head[u]=cnt;
    }
    struct Circle {//强连通分量 
    	int ind,minid,minpri;
    	//ind:入度 
    	//minid:当前SCC内最小编号 
    	//minpri:当前SCC内最小权值 
    }c[N];
    inline bool cmp(Circle a,Circle b){
    	return a.minid<b.minid;
    }
    inline void Initi(){
    	for(rg int i=1;i<N;i++){
    		c[i].minid=c[i].minpri=INF;
    	}
    }
    stack<int>s;
    void Tarjan(int now){//Tarjan板子 
    	dfn[now]=low[now]=++tim;
    	vis[now]=1,s.push(now);
    	for(rg int i=head[now];i;i=e[i].nxt){
    		int v=e[i].to;
    		if(!dfn[v]){
    			Tarjan(v);
    			low[now]=min(low[now],low[v]);
    		}else {
    			if(vis[v]){
    				low[now]=min(low[now],dfn[v]);
    			}
    		}
    	}
    	if(dfn[now]==low[now]){
    		tot++;
    		int yy;
    		do {
    			yy=s.top();
    			bel[yy]=tot;
    			vis[yy]=0,s.pop();
    			if(pri[yy])c[tot].minpri=min(c[tot].minpri,pri[yy]);
    			c[tot].minid=min(c[tot].minid,yy);
    		}while(yy!=now);
    	}
    }
    int main(){
    	Read(n),Read(p);
    	for(rg int i=1;i<=p;i++){
    		int pos,num;
    		Read(pos),Read(num);
    		pri[pos]=num;
    	}
    	Read(r);
    	for(rg int i=1;i<=r;i++){
    		int u,v;
    		Read(u),Read(v);
    		ade(u,v);
    	}
    	Initi();
    	for(rg int i=1;i<=n;i++){
    		if(!dfn[i])Tarjan(i);
    	}
    	for(rg int i=1;i<=n;i++){
    		for(rg int j=head[i];j;j=e[j].nxt){
    			int v=e[j].to;
    			if(bel[i]!=bel[v]){
    				c[bel[v]].ind++;
    			}
    		}
    	}
    	sort(c+1,c+1+tot,cmp);
    	for(rg int i=1;i<=tot;i++){
    		if(!c[i].ind){
    			if(c[i].minpri==INF){
    				printf("NO
    %d
    ",c[i].minid);
    				return 0;
    			}else {
    				ans+=c[i].minpri;
    			}
    		}
    	}
    	printf("YES
    %d
    ",ans);
    	return 0;
    }
    

    完结撒Flowey

    内容来自_ajhfff_的博客(https://www.cnblogs.com/juruoajh/),未经允许,不得转载。
  • 相关阅读:
    python-序列化与反序列化(loads、load、dumps、dump)
    STM32命名
    批处理参考
    Delphi通过管道执行外部命令行程序(cmd)并获取返回结果
    ubuntu使用备忘
    ubuntu14.04中安装QuartusII9.1步骤
    删除选中数据
    DBGridEh基本操作
    sqlserver 字符串函数
    使用 Delphi Xe 的 TDictionary
  • 原文地址:https://www.cnblogs.com/juruoajh/p/12633055.html
Copyright © 2011-2022 走看看