TTTTTTTTTTTTTT CF 645D 点的优先级
题意:给你n个节点,m对优先级关系,a[i] b[i]代表a[i]的优先级比b[i]高,现在问你至少需要前多少对关系就能确定所有节点的优先级;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <queue> #include <stack> #include <map> #include <algorithm> #include <set> using namespace std; typedef long long ll; typedef unsigned long long Ull; #define MM(a,b) memset(a,b,sizeof(a)); const double eps = 1e-10; const int inf = 0x3f3f3f3f; const double pi= acos (-1); const int mod=100000000; ll max(ll a,ll b) { return a>b?a:b;}; int min( int a, int b) { return a<b?a:b;}; vector< int > G[100005]; int deg[100005],mp[100005],a[100005],b[100005]; int main() { int n,m,u,v; while (~ scanf ( "%d %d" ,&n,&m)) { for ( int i=1;i<=n;i++) G[i].clear(); MM(deg,0); for ( int i=1;i<=m;i++) { scanf ( "%d %d" ,&a[i],&b[i]); G[b[i]].push_back(a[i]); deg[a[i]]++; } queue< int > q; for ( int i=1;i<=n;i++) if (deg[i]==0) q.push(i); int flag=1; while (q.size()) { if (q.size()>1) { flag=0; break ; } int u=q.front();q.pop(); for ( int i=0;i<G[u].size();i++) { int v=G[u][i]; deg[v]--; if (deg[v]==0) q.push(v); mp[v]=u; } } if (!flag) printf ( "-1\n" ); else { int cnt=0; for ( int i=1;i<=m;i++) { if (mp[a[i]]==b[i]) cnt++; if (cnt==n-1) { printf ( "%d\n" ,i); break ;} } } } return 0; } |
分析:很好的一道题,题目要求的其实就是什么时候能够找到一条从优先级最低的到
最高的一条路径,那么刚开始优先级最低的肯定是入度为0的点,接下来次底的呢?显然把与
最低的点相邻的边都删除了之后,入度为0的点就是次低的,并且只能有一个(因为存在一条
上述路径),若有>1个入度位0的点则无解,因为不存在合法路径,找到路径之后再枚举输入的边就好(因为两个节点之间至多一条边)
你说,我们都会幸福的,对吧?
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步