116 条题解
-
7
PowderHan LV 10 @ 8 年前
-
48 年前@
再来一个用队列top排序的
我是萌萌哒的分界线
我是萌萌哒的分界线
-
28 年前@
-
14 年前@
本题是一个裸的拓补排序题,与NOIP2020 T1 有异曲同工之妙,不同点在于今年的弱智题目卡了高精。
与他人不同的是,我这里选择了DFS 做法,与不同的队列做法不大一样,但是实质上没有任何差别,只不过是将广度优先改为了深度优先而已。 -
17 年前@
拓扑序判断下一个神经元,bfs就可以过了......
-
02 年前@
.
-
06 年前@
这个居然是也算NOIP提高组?笑杀老夫
-
07 年前@
-
07 年前@
注意m=0的情况,即输入层就是输出层
-
07 年前@
这题好蠢,浪费时间。只要一层一层遍历就行。我还以为遍历完一层那些非输出层但是c>0的还要继续发信号。
-
07 年前@
#include <iostream>
#include <cstdio>
#include <algorithm>
#define rep(i,n) for(i=1;i<=n;i++)
using namespace std;
int v[201], p[201], f[201];
int ru[201];
int h[201];
int que[201];
int chu[201];
int x, y;
struct node{
int a, b, c, n;
}d[100001];
int max1;
int f1;
int read(){
int x, f = 1;
char ch;
while(ch=getchar(),ch<'0'||ch>'9'){
if(ch=='-') f = -1;
}
x = ch-48;
while(ch=getchar(),'0'<=ch&&ch<='9'){
x = x * 10 + ch - 48;
}
return x*f;
}
int main(){
int i, j, n, m, a, b, c;
n = read(); m = read();
rep(i,n){
v[i] = read(); p[i] = read();
if(!v[i]){
v[i] = -p[i];
}
}
rep(i,m){
a = read(); b = read(); c = read();
d[i].a = a; d[i].b = b; d[i].c = c;
d[i].n = h[a]; h[a] = i;
ru[b]++;
chu[a]++;
}
rep(i,n) if(!ru[i]) que[++y] = i;
rep(x,y){
a = que[x];
for(i = h[a]; i; i = d[i].n){
b = d[i].b;
v[b] += v[a]*d[i].c;
ru[b]--;
if(!ru[b]&&v[b]>0){
que[++y] = b;
}
}
}
rep(i,n){
if(v[i]>0&&!chu[i]){
printf("%d %d\n", i, v[i]);
f1 = 1;
}
}
if(!f1) printf("NULL\n");
return 0;
}
图与样例不符啊!!!害我做了好久!!一直不知道输出的是输出层!!!!! -
08 年前@
不需要搜索
c++
#include<iostream>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
struct node
{
int output,bias;
bool ru=0,chu=0;
vector<int*> value;
vector<int>outedge,weight;
void calc()
{
if(ru)output = 0;
for(int i=0;i<value.size();++i)
output+=(*value[i])*weight[i];
output-=bias;
if(output<=0)output=0;
}
}nodes[210];
bool vis[210];
vector<vector<int>> ann;//用于保存神经元之间的关系
int n,p,layer;
int main()
{
//读入数据
cin>>n>>p;
for(int i=1;i<=n;++i)
scanf("%d%d",&nodes[i].output,&nodes[i].bias);
for(int i=1;i<=p;++i)
{
int a,b,w;
scanf("%d%d%d",&a,&b,&w);
nodes[b].value.push_back(&nodes[a].output);
nodes[a].outedge.push_back(b);
nodes[b].weight.push_back(w);
nodes[b].ru=nodes[a].chu=1;
}
ann.resize(1);
for(int i=1;i<=n;++i)
if(!nodes[i].ru)ann[0].push_back(i);
//建立神经网络
do{
memset(vis,0,sizeof(vis));
ann.resize(layer+2);
for(int i=0;i<ann[layer].size();++i)
for(int j=0;j<nodes[ann[layer][i]].outedge.size();++j)
{
int target = nodes[ann[layer][i]].outedge[j];
if(vis[target])continue;
ann[layer+1].push_back(target);
vis[target]=1;
}
}while(ann[++layer].size());
ann.resize(layer--);
//计算
for(int i=1;i<=ann.size();++i)
for(int j=0;j<ann[i].size();++j)
nodes[ann[i][j]].calc();
bool flag = 1;
//输出
for(int i=1;i<=n;++i)
if(!nodes[i].chu&&nodes[i].output)
{
cout<<i<<" "<<nodes[i].output<<endl;
flag = 0;
}
if(flag)cout<<"NULL"<<endl;
return 0;
}
-
08 年前@
那条式子是什么意思
-
08 年前@
为什么会有负数啊。。
坑。。 -
09 年前@
读懂题目就是胜利!
*************************我是萌萌哒的分界线*************************
Tip1.边有负数
Tip2.边为0也算有边
Tip3.Ci>0即可向下一层传输
Tip4.最后只输出Ci>0的解
Tip5.输入层由于没有上一层节点,不需要减去阈值PS.别问我为什么知道这么多,想想通过率我就心疼……
*************************我是萌萌哒的分界线*************************
```c++
/*
Name: Neural Network
Author: GoldenSun
Description: NOIP2003 High
*/
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,p;
int c[100],u[100];
int w[100][100];
int w_hash[100][100];
int q[100];
int q_count=0;
int d[100];
int maxd=0;
int c_hash[100];
int bfs(int q_i)
{
int j;c[q_i]-=u[q_i];
for(j=0;j<n;j++)
if(w_hash[q_i][j]==1)
{
if(c_hash[j]==0)
{
c_hash[j]=1;
q[q_count++]=j;
}if(d[j]<d[q_i]+1)
d[j]=d[q_i]+1;if(maxd<d[j])
maxd=d[j];if(c[q_i]>0)
c[j]+=w[q_i][j]*c[q_i];
}return 0;
}
int main()
{
memset(c,0,sizeof(c));
memset(u,0,sizeof(u));
memset(w,0,sizeof(w));
memset(q,0,sizeof(q));
memset(d,0,sizeof(d));
memset(c_hash,0,sizeof(c_hash));
memset(w_hash,0,sizeof(w_hash));int i;
int t1,t2;
int flag=0;scanf("%d%d",&n,&p);
for(i=0;i<n;i++)
{
scanf("%d%d",&c[i],&u[i]);if(c[i]>0)
{
c_hash[i]=1;
q[q_count++]=i;
c[i]+=u[i];
}
}
for(i=0;i<p;i++)
{
scanf("%d%d",&t1,&t2);
scanf("%d",&w[t1-1][t2-1]);
w_hash[t1-1][t2-1]=1;
}for(i=0;i<q_count;i++)
bfs(i);for(i=0;i<n;i++)
{
if(maxd==d[i]&&c[i]>0)
{
flag=1;
printf("%d %d\n",i+1,c[i]);
}
}
if(flag==0)
printf("NULL\n");return 0;
}
```
*************************我是萌萌哒的分界线*************************
编译成功测试数据 #0: Accepted, time = 15 ms, mem = 632 KiB, score = 20
测试数据 #1: Accepted, time = 0 ms, mem = 632 KiB, score = 20
测试数据 #2: Accepted, time = 0 ms, mem = 632 KiB, score = 20
测试数据 #3: Accepted, time = 0 ms, mem = 632 KiB, score = 20
测试数据 #4: Accepted, time = 0 ms, mem = 632 KiB, score = 20
Accepted, time = 15 ms, mem = 632 KiB, score = 100 -
09 年前@
这道题确实神经。。。温馨提示:输入层不用减去阀值^-^..
测试数据 #0: Accepted, time = 0 ms, mem = 964 KiB, score = 20
测试数据 #1: Accepted, time = 0 ms, mem = 964 KiB, score = 20
测试数据 #2: Accepted, time = 0 ms, mem = 968 KiB, score = 20
测试数据 #3: Accepted, time = 0 ms, mem = 964 KiB, score = 20
测试数据 #4: Accepted, time = 0 ms, mem = 964 KiB, score = 20
Accepted, time = 0 ms, mem = 968 KiB, score = 100 -
09 年前@
#include<iostream>
#include<iomanip>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<cstdlib>
#define N 10000
using namespace std;
int a[N][N],c[N],u[N];
int in[N],out[N],q[N];
double sum=1,now;
int fr,tail,flag;
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>c[i]>>u[i];
c[i]-=u[i];
}
for(int i=1;i<=m;i++)
{
int x,y,z;
cin>>x>>y>>z;
a[x][y]=z;
in[y]++;
out[x]++;
}
for(int i=1;i<=n;i++)
{
if(!in[i])q[++fr]=i;
}
while(fr>tail)
{
int k=q[++tail];
for(int i=1;i<=n;i++)
{
if(a[k][i])
{
c[i]+=c[k]*a[k][i];
in[i]--;
if(!in[i])q[++fr]=i;
}
}
}
for(int i=1;i<=n;i++)
{
if(!out[i]&&c[i]>0){cout<<i<<' '<<c[i]<<endl;flag=1;}
}
if(flag==0)cout<<"NULL";
return 0;
} -
09 年前@
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
const int MAXN = 300;int c[MAXN+10], u[MAXN+10], v[MAXN+10], used[MAXN+10], ans[MAXN+10];
vector<pair<int, int> > map[MAXN+10];int slen(int* a){
for(int i=MAXN; i>=1; i--)
if(a[i])
return i;
return 0;
}void bfs(int* a){
int len = slen(a);
int xin[MAXN+10] = {}, use[MAXN+10] = {}, flag = 1;
for(int i=1; i<=len; i++)
if(c[a[i]] > 0){
for(int j=0; j<map[a[i]].size(); j++){
int bri = map[a[i]][j].first;
c[bri] += map[a[i]][j].second*c[a[i]];
if(use[bri]) continue;
use[bri] = 1;
xin[flag++] = bri;
}
}
for(int i=1; i<flag; i++)
c[xin[i]] -= u[xin[i]];
if(flag == 1) {
for(int i=1; i<=MAXN; i++)
ans[i] = a[i];
return;
}
bfs(xin);
}int main()
{
int n, p;
scanf("%d%d", &n, &p);
for(int i=1; i<=n; i++)
scanf("%d%d", &c[i], &u[i]);
int flag = 1;
v[1] = 1;
for(int i=1; i<=p; i++){
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
map[x].push_back(make_pair(y, z));
if(c[x]>0 && !used[x]) v[flag++] = x, used[x] = 1;
}
bfs(v);
int len = slen(ans), qi = 1;;
sort(&ans[1], &ans[1]+len);
for(int i=1; i<=len; i++)
if(c[ans[i]] > 0){
printf("%d %d\n", ans[i], c[ans[i]]);
qi = 0;
}
if(qi)
printf("NULL");
return 0;
}
用BFS做的,,虽然A了,但并不知道算法到底对不对。。。
还有,这题描述太难懂了 -
09 年前@
按照拓扑序计算即可
评测结果
编译成功测试数据 #0: Accepted, time = 0 ms, mem = 1448 KiB, score = 20
测试数据 #1: Accepted, time = 0 ms, mem = 1452 KiB, score = 20
测试数据 #2: Accepted, time = 0 ms, mem = 1444 KiB, score = 20
测试数据 #3: Accepted, time = 0 ms, mem = 1452 KiB, score = 20
测试数据 #4: Accepted, time = 0 ms, mem = 1444 KiB, score = 20
Accepted, time = 0 ms, mem = 1452 KiB, score = 100#include<bits/stdc++.h>
using namespace std;
const int maxn = 209;
struct edge {
int to, w;
edge* next;
} E[100000], *pt = E, *head[maxn];inline void addedge(int u, int v, int w) {
pt->to = v; pt->w = w; pt->next = head[u]; head[u] = pt++;
}int deg[maxn], N, F[maxn], C[maxn];
bool output[maxn];void init() {
memset(deg, 0, sizeof deg);
memset(output, 0, sizeof output);
int m;
scanf("%d%d", &N, &m);
for(int i = 0; i < N; i++) {
scanf("%d%d\n", F + i, C + i);
C[i] = F[i] ? F[i] : -C[i];
}
while(m--) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w); u--; v--;
deg[v]++;
output[u] = true;
addedge(u, v, w);
}
}void dfs(int x) {
for(edge* e = head[x]; e; e = e->next) {
C[e->to] += e->w * C[x];
if(!--deg[e->to] && C[e->to] > 0) dfs(e->to);
}
}int main() {
init();
for(int i = 0; i < N; i++)
if(F[i]) dfs(i);
bool flag = false;
for(int i = 0; i < N; i++) if(!output[i] && C[i] > 0) {
flag = true;
printf("%d %d\n", i + 1, C[i]);
}
if(!flag)
puts("NULL");return 0;
} -
0