Aizu 2456 Usoperanto 贪心 拓扑排序
2015-10-02 21:30
330 查看
Usoperanto
Time Limit: 1 SecMemory Limit: 256 MB
题目连接
http://www.bnuoj.com/v3/contest_show.php?cid=6866#problem/JDescription
Usoperanto is an artificial spoken language designed and regulated by Usoperanto Academy. The academy is now in study to establish Strict Usoperanto, a variation of the language intended for formal documents.In Usoperanto, each word can modify at most one other word, and modifiers are always put before modifiees. For example, with a noun uso ("truth") modified by an adjective makka ("total"), people say makka uso, not uso makka. On the other hand, there have been no rules about the order among multiple words modifying the same word, so in case uso is modified by one more adjectivebeta ("obvious"), people could say both makka beta uso and beta makka uso.
In Strict Usoperanto, the word order will be restricted according to modification costs. Words in a phrase must be arranged so that the total modification cost is minimized. Each pair of a modifier and a modifiee is assigned a cost equal to the number of letters between the two words; the total modification cost is the sum of the costs over all modifier-modifiee pairs in the phrase. For example, the pair of makka and uso in a phrase makka beta uso has the cost of 4 for beta (four letters). As the pair of beta and uso has no words in between and thus the cost of zero, makka beta uso has the total modification cost of 4. Similarly beta makka uso has the total modification cost of 5. Applying the "minimum total modification cost" rule, makka beta uso is preferred to beta makka uso in Strict Usoperanto.
Your mission in this problem is to write a program that, given a set of words in a phrase, finds the correct word order in Strict Usoperanto and reports the total modification cost.
Input
The format of the input is as follows. N
M0 L0
...
MN-1 LN-1
M0 L0
...
MN-1 LN-1
The first line contains an integer N (1 ≤ N ≤ 106). N is the number of words in a phrase.
Each of the following N lines contains two integers Mi (1 ≤ Mi ≤ 10) and Li (-1 ≤ Li ≤ N - 1, Li ≠ i) describing the i-th word (0 ≤ i ≤ N-1). Mi is the number of the letters in the word. Li specifies the modification: Li = -1 indicates it does not modify any word; otherwise it modifies the Li-th word.
Note the first sample input below can be interpreted as the uso-beta-makka case.
Output
Print the total modification cost.Sample Input
3 3 -1 4 0 5 0
Sample Output
4
HINT
题意让你用题中给东西,构成一个链
输入是 ai,bi
表示ai必须要放在第bi个单词前面
代价是ai和bi之间的单词长度和
然后问你最小代价是多少
题解:
贪心就好了
这其实是一个图论题,你连接起来,就会构成一棵树
我们就每次贪心的选择最小的点权,且度数为1的点放在第一个,然后依次放
类似拓扑排序的一样做
代码:
//qscqesze #include <cstdio> #include <cmath> #include <cstring> #include <ctime> #include <iostream> #include <algorithm> #include <set> #include <bitset> #include <vector> #include <sstream> #include <queue> #include <typeinfo> #include <fstream> #include <map> #include <stack> typedef long long ll; using namespace std; //freopen("D.in","r",stdin); //freopen("D.out","w",stdout); #define sspeed ios_base::sync_with_stdio(0);cin.tie(0) #define maxn 1200500 #define mod 1001 #define eps 1e-9 #define pi 3.1415926 int Num; //const int inf=0x7fffffff; const ll inf=999999999; inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } //************************************************************************************* int n; int fa[maxn],ind[maxn]; ll sum[maxn]; int lst[maxn],top=0; int pre[maxn],nxt[maxn],to[maxn],cnt; void makeedge(int x,int y) { to[cnt]=y;nxt[cnt]=pre[x];pre[x]=cnt++; } int main() { memset(pre,-1,sizeof(pre)); scanf("%d",&n); for(int i=0;i<n;i++) { int x,y; scanf("%d%d",&x,&y); fa[i]=y; if(y>=0) { ind[y]++; makeedge(y,i); } sum[i]=x; } queue<int> q; while(!q.empty()) q.pop(); for(int i=0;i<n;i++) if(!ind[i]) q.push(i); ll ans=0,tmp=0; while(!q.empty()) { int s=q.front(); q.pop(); top=0; for(int p=pre[s];p!=-1;p=nxt[p]) { lst[++top]=sum[to[p]]; } sort(lst+1,lst+1+top); tmp=0; for(int i=1;i<top;i++) { tmp+=lst[i]; ans+=tmp; } if(fa[s]>=0) { --ind[fa[s]]; sum[fa[s]]+=sum[s]; if(!ind[fa[s]]) q.push(fa[s]); } } cout<<ans<<endl; }
相关文章推荐
- Aizu 2450 Do use segment tree 树链剖分+线段树
- http://jingyan.baidu.com/article/a3761b2b66fe141577f9aa51.html
- http://jingyan.baidu.com/article/a378c960630e61b329283045.html
- pat1014Waiting in Line (30)
- 智能机器人“小昆”的实现(五)MainActivty的实现及项目结束
- Aizu 2450 Do use segment tree (树链剖分)
- LightOJ 1138 Trailing Zeroes (III)
- 11i - 12 Gather Schema Statistics fails with Ora-20001 errors after 11G database Upgrade (文档 ID 781813.1)
- Hdu 4681 2013 Multi-University Training Contest 8 String
- http://wenku.baidu.com/link?url=UGoPtZviipHzi5SDIlGx6hPFWAHTPLFXcZ7ieD15JMd81DEHqjehvphVMhqELmOK4qXR74dTT9nW8VBoApBc7Kfb1ZWrNF_i24fY1YRHVki
- Aizu 2456 Usoperanto (贪心)
- UVa 11853 PaintBall
- 在linux进程中的信号屏蔽 http://blog.csdn.net/fjb2080/article/details/5174306
- vfork http://blog.csdn.net/tennysonsky/article/details/45847107
- Light oj 1038 - Race to 1 Again(概率dp)
- Tail call optimization in Scala
- 信号量sem_wait()的使用
- 关于信号量sem_wait的整理(转)
- system()函数 http://blog.csdn.net/ghevinn/article/details/7916126
- waitpid系统调用在Linux函数库中的原型是:http://blog.sina.com.cn/s/blog_602a39250100xfxx.html