您的位置:首页 > 其它

NKOI wjj的排列序列

2016-07-27 15:01 896 查看


输入格式

第一行包含一个正整数n和一个正整数m,意思如题所述。
接下来m行,每行两个整数ui,vi,表示一个限制条件。
输出格式

输出一行,表示
wjj 需要付出的最大代价。 
样例输入

3 1
3 1

样例输出

6

提示

数据范围
对于30%的数据,满足1≤n,m≤100。
对于100%的数据,满足1≤n,m≤10^5。 

样例解释 

题目要求要一个
1,2,3 的排列,并且限制条件为(3,1)。

符合要求的排列为(3,1,2),
(3,2,1),(2,3,1)。

(3,1,2)中,b1=3,b2=1,b3=1。所以代价为3+1+1=5。
(3,2,1)中,b1=3,b2=2,b3=1。所以代价为3+2+1=6。
(2,3,1)中,b1=2,b2=2,b3=1。所以代价为2+2+1=5。

#include<cstdio>
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
const int maxn=100005;
int n,m,du[maxn],f[maxn],cnt,Next
4000
[maxn<<1],End[maxn<<1],last[maxn];
inline void _read(int &x){
char t=getchar();bool sign=true;
while(t<'0'||t>'9')
{if(t=='-')sign=false;t=getchar();}
for(x=0;t>='0'&&t<='9';t=getchar())x=x*10+t-'0';
if(!sign)x=-x;
}
long long ans=0;
priority_queue<int>q;
vector<int>s;
void insert(int a,int b){
End[++cnt]=b;
Next[cnt]=last[a];
last[a]=cnt;
}
int main(){
_read(n);_read(m);
int i,j,x,y;
for(i=1;i<=m;i++){
_read(x);_read(y);
du[y]++;
insert(x,y);
}
for(i=1;i<=n;i++)
if(du[i]==0)
q.push(i);
s.push_back(0);
while(!q.empty()){
int temp=q.top();
q.pop();
s.push_back(temp);
for(i=last[temp];i;i=Next[i]){
du[End[i]]--;
if(du[End[i]]==0)q.push(End[i]);
}
}
x=maxn;
for(i=1;i<s.size();i++){
x=min(x,s[i]);
ans+=x;
}
cout<<ans;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: